Search code examples
matlabmatlab-figurematlab-guide

MATLAB: How to store clicked coordinates (peakpoints) continuosly from time series plot even after panning etc.


I am currently working on a matlab GUI where I need to click unwanted peak points (not to delete them) and store their results in a matrix (continuously). I am using a pushbutton with the following code to collect the points and store results. However, when I clicked the points only the last clicked results stores (not all the clicked points). Also, since it is a continuous plot I am using a PAN pushbutton to move the data. Hence, I would like to do the following:

1)For a pushbutton click (to collect peaks from getpts function) I want to click and collect several points (store and append the values continuously for each click). Also, I want the array to be active even after I use the PAN button to move the plot. 2) I want to create another pushbutton to end the task (asking the user to "do you want to stop collecting the peak points", stop collecting the points and store the entire clicked results in an array)

axes(handles.axes1);
[ptsx1,ptsy1] = getpts(gcf);
idx = knnsearch([t',fbsum],[ptsx1 ptsy1],'k',1)
if evalin('caller', 'exist(''xArray'',''var'')')
  xArray = evalin('caller','xArray');
 else 
  xArray = [];
 end
 xArray = [xArray; idx] %
 assignin('caller','xArray',xArray); `% save to base`
 save('xArray.mat','xArray');

Sorry, this is my first post and please accept my apology and please clarify if something is not clear. Thanks in advance.


Solution

  • EDIT: Using a GUIDE based GUI Instead

    In Matlab command window define your X & Y

    >> x = 0:.1:4*pi;
    >> y = sin(x);
    >> y(10:10:end) = 2; %With some bad points to mark
    

    Then run the GUI, select Start Marking, mark some points Pan around etc.:

    >> plotTest(x,y)
    

    After exiting the GUI look at the globla IDX_STORE:

    >> global IDX_STORE
    >> IDX_STORE
    
    IDX_STORE =
    
        10    30    40
    

    If you want the x , y values marked then it is just

    >> markedX = x(IDX_STORE);
    >> markedY = y(IDX_STORE);
    

    The GUI is laid out Like this picture.

    GUI Code Looks like this:

    function varargout = plotTest(varargin)
    % Begin initialization code - DO NOT EDIT
    gui_Singleton = 1;
    gui_State = struct('gui_Name',mfilename,'gui_Singleton',gui_Singleton,'gui_OpeningFcn', @plotTest_OpeningFcn, ...
                       'gui_OutputFcn',  @plotTest_OutputFcn,'gui_LayoutFcn',[] ,'gui_Callback',[]);
    if nargin && ischar(varargin{1})
        gui_State.gui_Callback = str2func(varargin{1});
    end
    if nargout
        [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
    else
        gui_mainfcn(gui_State, varargin{:});
    end
    % End initialization code - DO NOT EDIT
    
    % --- Executes just before plotTest is made visible.
    function plotTest_OpeningFcn(hObject, eventdata, handles, varargin)
    global IDX_STORE
    IDX_STORE = [];
    handles.output = [];
    if numel(varargin) ~= 2
        handles.closeFigure = true;
    else    
        x = varargin{1}; y =varargin{2};
        handles.l = plot(handles.axes1,x,y);
        hold(handles.axes1,'on')
        handles.axes1.ButtonDownFcn = {@clickCallback,handles};
        handles.l.ButtonDownFcn     = {@clickCallback,handles};
        guidata(hObject, handles);
    end
    
    % --- Outputs from this function are returned to the command line.
    function varargout = plotTest_OutputFcn(hObject, eventdata, handles) 
    varargout{1} = [];
    if (isfield(handles,'closeFigure') && handles.closeFigure)
        errordlg('Nothing Passed in!')    
    end
    
    % --- Executes on button press in markToggle.
    function markToggle_Callback(hObject, eventdata, handles)
    switch handles.markToggle.Value
        case 1
            handles.markToggle.String = 'Stop Marking';
        case 0
            handles.markToggle.String = 'Start Marking';        
    end
    
    function clickCallback(hObj,evtData,handles)
    global IDX_STORE
    if handles.markToggle.Value == 0
        return %Do Nothing if toggle not pressed.
    end
    coordinates = handles.axes1.CurrentPoint(1,1:2); %Get coordinates of mouse click
    idx = knnsearch([handles.l.XData' handles.l.YData'],coordinates);%Find closest point in line data
    IDX_STORE = unique([IDX_STORE idx]); %Store the index.   
    mH = findobj(handles.axes1,'tag','markLine');%Add some markers to see what you are doing.
    if isempty(mH) %Make the marker plot if it doesn't exist
        plot(handles.axes1, handles.l.XData(IDX_STORE),handles.l.YData(IDX_STORE),'rO','tag','markLine')
    else%If it does exist then update the markers
        mH.XData = handles.l.XData(IDX_STORE);    mH.YData = handles.l.YData(IDX_STORE);
    end
    guidata(hObj,handles); %Save handles structure