Search code examples
matlabimage-processingplothandles

How to change output text in datacursor mode for a plot with double y-axis with single x-axis


I have the following code:

datee = {'23-10-201511:36:24', '23-10-201511:37:24', '23-10-201511:38:24', '23-10-201511:39:24', '23-10-201511:40:24', '23-10-201511:41:24', '23-10-201511:42:24', '23-10-201511:43:24', '23-10-201511:44:24', '23-10-201511:45:24'};
Temperature = [23.6, 23.6, 23.7, 23.7, 23.7, 23.7, 23.7, 23.7, 23.7, 23.7];
Humidity = [40, 40, 40, 39.9, 39.8, 39.7, 39.8, 39.8, 39.8, 39.8];
C = datenum(datee,'dd-mm-yyyyHH:MM:SS'); 
[ax,h1,h2] = plotyy(C,Temperature,C,Humidity)
hold on;
datestr(C); 
datetick(ax(1),'x','HH:MM','keepticks');
datetick(ax(2),'x','HH:MM','keepticks');
xlabel('time [hours]');
ylabel(ax(1),'Temperature [°C]');
ylabel(ax(2),'Humidity [%rH]');



dcm_obj = datacursormode(gcf); 
set(dcm_obj,'UpdateFcn',@myfunction);

function [output_txt] = myfunction(~,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= {['time: ', datestr(pos(1))],...                           
    ['Temperature: ',num2str(pos(2),4)]};

 output_txt= {['time: ', datestr(pos(1))],...                           
    ['Humidity: ',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)];
end

If I use this code, I see only time and temperature variables for both the y axes but not the humidity variable.

I would like to see something like if I click on one y-axis it must display time and temperature and for other y axis, time and humidity.


Solution

  • If I'm interpreting your question correctly, you want to have different data tips based on which line is clicked on. One method to accomplish this is to compare the Target of your event_obj to the handles of your line objects returned by plotyy:

    function testcode
    datee = {'23-10-201511:36:24', '23-10-201511:37:24', '23-10-201511:38:24', '23-10-201511:39:24', '23-10-201511:40:24', '23-10-201511:41:24', '23-10-201511:42:24', '23-10-201511:43:24', '23-10-201511:44:24', '23-10-201511:45:24'};
    Temperature = [23.6, 23.6, 23.7, 23.7, 23.7, 23.7, 23.7, 23.7, 23.7, 23.7];
    Humidity = [40, 40, 40, 39.9, 39.8, 39.7, 39.8, 39.8, 39.8, 39.8];
    C = datenum(datee,'dd-mm-yyyyHH:MM:SS');
    [ax,h1,h2] = plotyy(C,Temperature,C,Humidity);
    hold on;
    datestr(C);
    datetick(ax(1),'x','HH:MM','keepticks');
    datetick(ax(2),'x','HH:MM','keepticks');
    xlabel('time [hours]');
    ylabel(ax(1),'Temperature [°C]');
    ylabel(ax(2),'Humidity [%rH]');
    
    
    dcm_obj = datacursormode(gcf);
    set(dcm_obj,'UpdateFcn',{@myfunction, [h1, h2]});
    end
    
    function [output_txt] = myfunction(~,event_obj, linehandles)
    % 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');
    targetline = get(event_obj, 'Target');
    
    switch targetline
        case linehandles(1)
            output_txt = {['Time: ', datestr(pos(1))], ...
                ['Temperature: ',num2str(pos(2),4)] ...
                };
        case linehandles(2)
            output_txt = {['Time: ', datestr(pos(1))], ...
                ['Humidity: ',num2str(pos(2),4)] ...
                };
        otherwise
            % No match
            output_txt = {['X: ', datestr(pos(1))], ...
                ['Y: ',num2str(pos(2),4)] ...
                };
    end
    
    % 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)];
    end
    end
    

    Two main changes here: I have passed h1 and h2 to your callback for use with the case-switch statement I added. You can use an equivalent if-else statement but I personally find case-switch more elegant.

    And the corresponding datatips:

    yay yay2