MATLAB: Get position when using uicontextmenu

buttondownfcnclick pointguiMATLABmatlab guiselect point

I'm trying to code an interface that alows the user to perform some actions on a set of points visualized as a scatter plot.
To do so, I thought I could use a contextmenu, where the user could right-click on a point and decide what to do among a list of actions.
However when using uicontextmenu, I could not get nor the handle of the parent, nor the position (or index) of the point the user is clicking.
Consider this example
function test()
figure
x = randn(1,20);
y = randn(1,20);
menu = uicontextmenu();
hs = scatter(x,y,'UIContextMenu',menu);
uimenu(menu,'Label','Do something with this point','Callback',@something)
end
function something(src,evnt)
fprintf('x = %f, y = %f',x,y)
end
I know a workaround is to pass the parent to the function, is to call
uimenu(menu,'Label','Do something with this point','Callback',{@something, hs})
and define
function something(src,evnt,parent)
fprintf('%s\n',class(parent))
end
but this doesn't help me understanding on which point the user has clicked, as the input to "something" is defined during creation ans src,evnt do not contain the information I'm looking for.
Is there a workaround?

Best Answer

Instead of a context menu, use a ButtonDownFcn that responds to a mouse click on the object. It's lighter weight than a context menu and requires only 1 click rather than a right-click + selection.
Here's a demo using your idea: It outputs the (x,y) coordinates to the command window and marks the most recently selected coordinate with a red 'x'. hObj is the handle to the line object you're clicking. eventM is a structure that contains the coordinates of the point you selected and the button used to select it.
figure
x = randn(1,20);
y = randn(1,20);
% menu = uicontextmenu();
hs = scatter(x,y);
hs.ButtonDownFcn = @clickPointFcn;
hold on
function clickPointFcn(hObj,event)
% Do whatever you want with that....
fprintf('x = %f, y = %f\n',event.IntersectionPoint(1:2))
% Search and remove previous 'recent selection'
delete(findall(hObj.Parent, 'Tag','recentSelection'))
% Add 'x' to mark selection
plot(event.IntersectionPoint(1),event.IntersectionPoint(2), 'rx', 'tag','recentSelection')
end