Effacer les filtres
Effacer les filtres

Select Points on Plot (Code Included)

2 vues (au cours des 30 derniers jours)
Daniel
Daniel le 11 Fév 2011
I am trying to select points on a raster plot in a GUIDE GUI. The process begins by clicking an edit button and should end when the user clicks the done button. I would like to select points(red) with a left mouse click and unselect points(green) with a right mouse click.
Currently, the ginput runs until 'c' number of points have been selected... even if the user clicks the done button. If I remove plotting 'stance' and change 'c' to '1,' one row will plot... otherwise it will not plot. When I click the done button, any plotted points vanish.
1. I don't understand why ginput continues to run after the loop should have closed.
2. I don't understand why it will not plot the data and why the data dissappears when I click the done button.
This is the code that I am using so far.
[r,c]=size(degrees);
editon=1;
while editon > 0.5;
editon=getappdata(handles.edit_button,'edit_on'); %Set editon to '0' by clicking the 'Done' button
[xi,yi,button] = ginput(c);
x = round(xi);
y = round(yi);
if button == 1 %Select row and change to 'red'
plot(degrees(:,x),y,'r*')
plot(stance(x,1),y,'ro')
elseif button == 3; %Select row and change to 'green'
plot(degrees(:,x),y,'g*')
plot(stance(x,1),y,'go')
end
end
'degrees' is a matrix. The column number of 'degrees' turn into the row number on the plot and the points in the columns of 'degrees'make up the points on the rows. 'stance' is a column vector. It has as many rows as 'degrees' has columns.
Any help is greatly appreciated. Thanks ~Dan
  1 commentaire
Paulo Silva
Paulo Silva le 18 Fév 2011
Instead of having a button DONE why doesn't the user just click ENTER or other key on the keyboard?
[r,c]=size(degrees);
button=1;
while ((button==1) | (button==3));
[xi,yi,button] = ginput(c);
x = round(xi);
y = round(yi);
if button == 1 %Select row and change to 'red'
plot(degrees(:,x),y,'r*')
plot(stance(x,1),y,'ro')
elseif button == 3; %Select row and change to 'green'
plot(degrees(:,x),y,'g*')
plot(stance(x,1),y,'go')
end
end

Connectez-vous pour commenter.

Réponse acceptée

Matt Tearle
Matt Tearle le 12 Fév 2011
I was actually playing with this today (because I am that much of a dork). There might be a way around ginput, but I wonder if it's actually easier to go a different route altogether, and use the ButtonDownFcn property instead.
So... sorry this is a bit huge, but try copy-n-pasting this and see if the flow is what you're looking for. If so, we can deconstruct it, if you can't fathom it :) (The changepointer callback is not necessary -- just me being fancy.)
function getgraphinput
hf = figure;
ha = axes('position',[0.1 0.3 0.8 0.6]);
x = linspace(0,1);
hp = plot(x,sin(5*pi*x));
set(hp,'hittest','off')
hstart = uicontrol('style','pushbutton','string','Start',...
'units','normalized','position',[0.2 0.1 0.2 0.1],...
'callback',@startgin);
hstop = uicontrol('style','pushbutton','string','Done',...
'units','normalized','position',[0.6 0.1 0.2 0.1],...
'callback',@stopgin,'enable','off');
function startgin(hObj,handles,eventdat)
set(hObj,'Enable','off')
set(hstop,'enable','on')
set(hf,'WindowButtonMotionFcn',@changepointer)
set(ha,'ButtonDownFcn',@getpoints)
end
function stopgin(hObj,handles,eventdat)
set(hObj,'Enable','off')
set(hstart,'enable','on')
set(hf,'Pointer','arrow')
set(hf,'WindowButtonMotionFcn',[])
set(ha,'ButtonDownFcn',@getpoints)
xy = getappdata(hf,'xypoints');
line(xy(:,1),xy(:,2))
end
function changepointer(hObj,handles,eventdat)
axlim = get(ha,'Position');
fglim = get(hf,'Position');
x1 = axlim(1)*fglim(3) + fglim(1);
x2 = (axlim(1)+axlim(3))*fglim(3) + fglim(1);
y1 = axlim(2)*fglim(4) + fglim(2);
y2 = (axlim(2)+axlim(4))*fglim(4) + fglim(2);
pntr = get(0,'PointerLocation');
if pntr(1)>x1 && pntr(1)<x2 && pntr(2)>y1 && pntr(2)<y2
set(hf,'Pointer','crosshair')
else
set(hf,'Pointer','arrow')
end
end
function getpoints(hObj,~,~)
cp = get(hObj,'CurrentPoint');
line(cp(1,1),cp(1,2),'linestyle','none',...
'marker','o','color','r')
xy = getappdata(hf,'xypoints');
xy = [xy;cp(1,1:2)];
setappdata(hf,'xypoints',xy);
end
end

Plus de réponses (3)

Matt Tearle
Matt Tearle le 11 Fév 2011
Maybe I'm misunderstanding the interaction process, but it seems like you enter the loop, then (probably) get to the ginput line, click c points, then before you'd have a chance to hit 'done', it will complete the while loop and start again. Once invoked, ginput won't quit until you've clicked the c points asked for (or you hit enter). IOW, the callback associated with clicking 'done' won't interrupt ginput.
The way it's written, I'd guess that, once you hit 'done', you'd still have finish the c clicks for that pass through the loop, then another lot for the next pass through (because editon is updated at the beginning of the loop), then it would quit.

Daniel
Daniel le 12 Fév 2011
That sounds right. Would it help to update editon after ginput?
If I change to c=1, the program will select and plot one row of data points. It will not repeat the loop and continue to select points until the user clicks done. When I click done, the newly plottted points disappear.
If I change the code to c=1, is there a way to continue the loop and prevent the points from disappearing?
I previously had tried using/modifing 'Graphical data selection tool' by John D'Errico as a base for writing my code. However, I was unable to make the needed changes.
link: http://www.mathworks.com/matlabcentral/fileexchange/13857

Daniel
Daniel le 18 Fév 2011
Wow Matt... That looks great but you lost me. I figured it out the way I had started. Here's the jist of the final code:
[r,c]=size(degrees);
while (getappdata(handles.edit_button,'edit_on') == 1)
[xi,yi,button] = ginput(1);
x = round(xi);
y = round(yi);
if x>=0 && x<=360 && y>=1 && y<=c; %Nothing happens if
%you click outside
%the window
for repeat=1:c;
if button == 1;
plot(degrees(repeat,y),y,'r.')
elseif button == 3;
plot(degrees(repeat,y),y,'k.')
end
end
if button == 1;
plot(stance(1,y),y,'ro')
elseif button == 3;
plot(stance(1,y),y,'ko')
end
end
end
hold off
guidata(hObject, handles);
P.S. Sorry it took so long to respond... spent a few days at home sick with the flu. Thanks for the code... going to try to digest it when I have a little more free time.

Catégories

En savoir plus sur Migrate GUIDE Apps dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by