Search code examples
matlabpause

How to extract arbitrary number of data points from data tip cursor in Matlab?


I am trying to display a sequence of figures (in the example code below, 2 figures) such that I will go through each figure one by one and click on some points and output the (x,y) position of the points from the cursor. Following some online help, I use the pause function, I click on one point, press a key which outputs the (x,y) data to the Matlab terminal using datacursormode and getCursorInfo functions and then click on the next point. I don't know how many points I am going to select in each figure but let's say it is going to be less than 10. Therefore, I am using a for loop (for rc1=1:10) with a pause statement in it. The problem is I don't know how to exit this loop when I am finished with a fewer number of points (lets say at rc1=5) and move to the next figure. How do I do this ? If the code could take some indication that I have finished selecting points from a current figure and let me break out of the rc1=1:10 loop (for example, some kind of if (condition) continue statement after if isfield ... end should work).

clc
clearvars
close all

for rc2=1:2
    
    figure;
    
    x = linspace(0,10,150);
    y = cos(5*x);
    fig = gcf;
    plot(x,y)
    % Enable data cursor mode
    datacursormode on
    dcm_obj = datacursormode(fig);
    % Set update function
    set(dcm_obj,'UpdateFcn',@myupdatefcn)
    % Wait while the user to click
    disp('Click line to display a data tip, then press "Return"');
    
    for rc1=1:10
        pause
        % Export cursor to workspace
        info_struct = getCursorInfo(dcm_obj);
        if isfield(info_struct, 'Position')
            fprintf('%.2f %.2f \n',info_struct.Position);
        end
        
     end
    
end

function output_txt = myupdatefcn(~,event_obj)
% ~            Currently not used (empty)
% event_obj    Object containing event data structure
% output_txt   Data cursor text
pos = get(event_obj, 'Position');
output_txt = {['x: ' num2str(pos(1))], ['y: ' num2str(pos(2))]};
end

Solution

  • OK, I figured it out. Adding a try, catch, break, end sequence in the inner loop and putting the pause, getCursorInfo, isfield segment within the try section made it work. Now I select few points, simply close the current figure, press a key and move on to the next figure. This works.

    clc
    clearvars
    close all
    
    for rc2=1:2
        
        figure;
        
        x = linspace(0,10,150);
        y = cos(5*x);
        fig = gcf;
        plot(x,y)
        % Enable data cursor mode
        datacursormode on
        dcm_obj = datacursormode(fig);
        % Set update function
        set(dcm_obj,'UpdateFcn',@myupdatefcn)
        % Wait while the user to click
        disp('Click line to display a data tip, then press "Return"');
        
        for rc1=1:10
            % Export cursor to workspace
            try
                pause
                info_struct = getCursorInfo(dcm_obj);
                if isfield(info_struct, 'Position')
                    fprintf('%.2f %.2f \n',info_struct.Position);
                end
            catch
                break;
            end
         end
        
    end
    
    function output_txt = myupdatefcn(~,event_obj)
    % ~            Currently not used (empty)
    % event_obj    Object containing event data structure
    % output_txt   Data cursor text
    pos = get(event_obj, 'Position');
    output_txt = {['x: ' num2str(pos(1))], ['y: ' num2str(pos(2))]};
    end