2016-03-08 31 views
1

按照其他頁面上的說明,例如MATLAB自定義數據提示圖片

http://blogs.mathworks.com/videos/2011/10/19/tutorial-how-to-make-a-custom-data-tip-in-matlab/ http://it.mathworks.com/help/matlab/ref/datacursormode.html http://it.mathworks.com/matlabcentral/answers/68079-how-to-add-additional-info-to-the-data-cursor

我寫了一個定製的回調函數的數據提示給我點上一XY圖索引以及它們x和y座標:

function output_txt = customCallback_DataTip(obj,event_obj) 
% Display the position of the data cursor 
% obj   Currently not used (empty) 
% event_obj Handle to event object 
% output_txt Data cursor text string (string or cell array of strings). 

pos = get(event_obj,'Position'); 
output_txt = {['X: ',num2str(pos(1),4)],... 
    ['Y: ',num2str(pos(2),4)]}; 

% If there is a Z-coordinate in the position, display it as well 
if length(pos) > 2 
    output_txt{end+1} = ['Z: ',num2str(pos(3),4)]; 
else % 2D plot: write index of current point 
    i = find(event_obj.Target.XData == pos(1), 1); 
    output_txt{end+1} = ['i: ',num2str(i)]; 
end 

這段代碼從MATLAB建議的默認回調開始,並且在繪圖是3D時添加z座標信息。由於我經常需要知道圖上某點的數組索引,所以在MATLAB啓動時會自動啓用自定義回調函數。

現在,每當我繪製的圖像(例如,經由imagesc)我想有「正常」的圖像數據提示:

image datatip

即具有在其上索引/ RGB信息。我如何修改回調函數以獲得此行爲?

編輯:我想修改我的定製的回調使其當我使用的是圖像的數據提示會自動顯示類似於默認MATLAB默認數據提示的東西。

回答

4

要做到這一點,您可以檢查event_obj.Target的類型並作出相應的響應。

get(event_obj.Target, 'type') 

所有圖像(無論是imagescimage,或imshow)將有imageType

isImage = strcmpi(get(event_obj.Target, 'type'), 'image') 

然後,您可以提取圖像數據。如果您有索引圖像,還可以通過顏色表來確定要進入數據提示的所有其他信息。

cdata = get(event_obj.Target, 'cdata'); 
cmap = colormap(ancestor(event_obj.Target, 'axes')); 

把這一切放在一起,我會修改你的自定義數據提示回調是這樣的。

function output_txt = callback(obj, event_obj, clims) 
    % Get the cursor location 
    pos = get(event_obj, 'Position'); 

    output_txt = {sprintf('[X,Y]: [%i, %i]', pos(1), pos(2))}; 

    if strcmpi(get(event_obj.Target, 'type'), 'image') 
     % Get the image data 
     cdata = get(event_obj.Target, 'CData'); 

     % Check to ensure pos is in range 
     if pos(1) < 1 || pos(1) > size(cdata, 2) || ... 
      pos(2) < 1 || pos(2) > size(cdata, 1) 
      rgb = {NaN, NaN, NaN}; 
      newline = sprintf('[R,G,B]: [%0.4f %0.4f %0.4f]', rgb{:}); 
      output_txt = cat(1, output_txt, newline); 
      return 
     end 

     % If the image is RGB 
     if size(cdata, 3) == 3 
      rgb = num2cell(cdata(pos(2), pos(1), :)); 

     % If this is an indexed image 
     else 
      index = cdata(pos(2), pos(1)); 

      % Figure out the colormap 
      hax = ancestor(event_obj.Target, 'axes'); 
      cmap = colormap(hax); 

      % If the CData is scaled, we need to scale to the colormap 
      if strcmpi(get(event_obj.Target, 'CDataMapping'), 'scaled') 
       value = (index - clims(1)) * size(cmap, 1)/diff(clims); 
      else 
       value = index; 
      end 

      % Determine RGB value from colormap 
      rgb = num2cell(ind2rgb(round(value), cmap)); 

      if round(index) == index 
       newline = sprintf('Index: %d', index); 
      else 
       newline = sprintf('Index: %.4f', index); 
      end 

      % Generate datatip text 
      output_txt = cat(1, output_txt, newline); 
     end 

     output_txt = cat(1, output_txt, ... 
       sprintf('[R,G,B]: [%0.4f %0.4f %0.4f]', rgb{:})); 

    % Otherwise we use your custom datatip for plots 
    else 
     index = find(event_obj.Target.XData == pos(1), 1); 

     pos = get(event_obj, 'Position'); 
     output_txt = { sprintf('X: %0.4f', pos(1)); 
         sprintf('Y: %0.4f', pos(2))}; 

     % If there is a Z-coordinate in the position, display it as well 
     if length(pos) > 2 
      output_txt{end+1} = sprintf('Z: %0.4f', pos(3)); 
     else % 2D plot: write index of current point 
      output_txt{end+1} = sprintf('i: %d', index); 
     end 
    end 
end 

如果您注意到,我將一個附加變量(clims)傳遞給回調函數。這是因爲有些版本實際上並不允許我從內的數據提示UpdateFcn中查詢座標軸屬性。所以這意味着你將不得不改變你的匿名函數。

h = datacursormode(fig); 
set(h, 'Enable', 'on') 

% Here I have to pass the `clims` because I can't fetch them inside 
set(h, 'UpdateFcn', @(dt,e)callback(dt, e, caxis(ancestor(dt.Host, 'axes')))); 

使用這個,我能夠顯示適當的顯示爲圖表和圖像(索引和RGB)。

enter image description here

+0

太棒了。超過了我的預期。很痛! – lampo808

+0

爲防萬一別人想複製粘貼你的代碼:在最後一個'else'後面,缺少以下行: 'i = find(event_obj.Target.XData == pos(1),1);' – lampo808

+0

@ lampo808謝謝你指出。我已經更新了包含您的代碼的答案。 – Suever