How to move a plotted line vertically with mouse in a GUI?

57 views (last 30 days)
Hi, I'm trying to build a GUI that plots several signals in the same graph above each other. Now, to compare the general waveforms, I would like to be able to manually click a plotted line with the mouse and drag it up to another plotted line to visually compare the two. Does anybody know if this is possible and how to do this? Maybe this is already something built into matlab? Please help.
Thanks

Accepted Answer

Geoff Hayes
Geoff Hayes on 27 Jul 2014
Ruben - here is a quick and rough way to do what I think that you want. It makes several assumptions which are hopefully valid for what you are trying to do, namely that plot (or some equivalent) function is used to plot the data on the 2D axes - so we have access to the x and y data that makes up the graphic. I've used GUIDE to mock up a GUI - it has a single axes (named axes1) and a push button (named pushbutton1). The button is used to plot some data on the axes. Its callback is
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% define an array of colours
colours = {'b','r','g','k','m','y'};
% is the plot handles field defined for the handles structure?
if ~isfield(handles,'plotHandles');
handles.plotHandles = [];
end
% determine the number of handles (a maximum of six are plotted)
numHandles = mod(length(handles.plotHandles),6);
% get the x and y data for the sine wave, offset by the number of handles
x = -2*pi:0.01:2*pi;
y = sin(x) + numHandles;
% plot the data
h = plot(handles.axes1,x,y,colours{numHandles+1});
% update the plot handles to the array of plot handles
handles.plotHandles = [handles.plotHandles ; h];
% save the data
guidata(hObject,handles);
The above just plots up to six sine waves on the axes. The important part is the saving of the plot graphics handle to the handles structure. This will allow us to manipulate the data later on.
Now, in order to enable the user to move a graphic object on the axes, we are going to assign three callbacks to the GUI/figure. In the Opening function (myGuiName_OpeningFcn), add the following code
set(hObject, ...
'WindowButtonDownFcn', @mouseDownCallback, ...
'WindowButtonUpFcn', @mouseUpCallback, ...
'WindowButtonMotionFcn', @mouseMotionCallback);
hObject is our GUI/figure, and we are going to create callbacks for the (mouse) button down, up and motion events.
Each callback (within our m-file) is then defined.
The purpose of the mouseDownCallback is to check to see if the mouse down event is within axes1 (as opposed to anywhere else within the GUI). If this is true, then given the position within axes1, find (using the Euclidean distance equation) which plot graphics is closest to this position. This information is then saved for the mouse motion callback.
function mouseDownCallback(figHandle,varargin)
% get the handles structure
handles = guidata(figHandle);
% get the position where the mouse button was pressed (not released)
% within the GUI
currentPoint = get(figHandle, 'CurrentPoint');
x = currentPoint(1,1);
y = currentPoint(1,2);
% get the position of the axes within the GUI
axesPos = get(handles.axes1,'Position');
minx = axesPos(1);
miny = axesPos(2);
maxx = minx + axesPos(3);
maxy = miny + axesPos(4);
% is the mouse down event within the axes?
if x>=minx && x<=maxx && y>=miny && y<=maxy
% do we have graphics objects?
if isfield(handles,'plotHandles')
% get the position of the mouse down event within the axes
currentPoint = get(handles.axes1, 'CurrentPoint');
x = currentPoint(2,1);
y = currentPoint(2,2);
% we are going to use the x and y data for each graphic object
% and determine which one is closest to the mouse down event
minDist = Inf;
minHndl = 0;
for k=1:length(handles.plotHandles)
xData = get(handles.plotHandles(k),'XData');
yData = get(handles.plotHandles(k),'YData');
dist = min((xData-x).^2+(yData-y).^2);
if dist<minDist
minHndl = handles.plotHandles(k);
minDist = dist;
end
end
% if we have a graphics handle that is close to the mouse down
% event/position, then save the data
if minHndl~=0
handles.mouseIsDown = true;
handles.movingPlotHndle = minHndl;
handles.prevPoint = [x y];
guidata(figHandle,handles);
end
end
end
The purpose of the mouseUpCallback is to just reset any fields that correspond to the moving of the graphic, indicating that we are finished with the move.
function mouseUpCallback(figHandle,varargin)
% get the handles structure
handles = guidata(figHandle);
if isfield(handles,'mouseIsDown')
if handles.mouseIsDown
% reset all moving graphic fields
handles.mouseIsDown = false;
handles.movingPlotHndle = [];
handles.prevPoint = [];
% save the data
guidata(figHandle,handles);
end
end
Finally, the purpose of mouseMotionCallback is to move the graphic from the previous position to the current one.
function mouseMotionCallback(figHandle,varargin)
% get the handles structure
handles = guidata(figHandle);
if isfield(handles,'mouseIsDown')
if handles.mouseIsDown
currentPoint = get(handles.axes1, 'CurrentPoint');
x = currentPoint(2,1);
y = currentPoint(2,2);
% compute the displacement from previous position to current
xDiff = x - handles.prevPoint(1);
yDiff = y - handles.prevPoint(2);
% adjust this for the data corresponding to movingPlotHndle
xData = get(handles.movingPlotHndle,'XData');
yData = get(handles.movingPlotHndle,'YData');
set(handles.movingPlotHndle,'YData',yData+yDiff,'XData',xData+xDiff);
handles.prevPoint = [x y];
% save the data
guidata(figHandle,handles);
end
end
I've attached the code to this answer. Hope that it helps!
  3 Comments
leydy Garcia
leydy Garcia on 18 Feb 2020
Hi Geoff. This is great. If you wanted to move two lines, and got values of XData and YData for each line, how would you adjust this code?
thanks
Geoff Hayes
Geoff Hayes on 18 Feb 2020
leydy - do you mean to move two lines at the same time? If so, I'm not sure how you would go about selecting which lines to move. The above (if I remember correctly) just finds the line (graphics object) that is closest to the mouse cursor position (when you press the button on the mouse).

Sign in to comment.

More Answers (0)

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!