dragging a selected point within uiaxes

Hello,
wihin standard figure and axes, I can easely move point.
These points are the graphical representation of complex numbers, so when I move a point I must move its conjugate accordingly.
All works fine with classical figure. I currently use gco to obtain the current point handle. What would be the equivalent with uiaxes within an uifigure?
Best Regards

1 Comment

"dragging" a plotted point isn't supported in any type of figure although some objects such as text or a point object are draggable.

Sign in to comment.

 Accepted Answer

Adam Danz
Adam Danz on 26 Jan 2021
Edited: Adam Danz on 26 Jan 2021
HandleVisibility is set to off by default with uifigures and this prevents gcf/gca/gco from accessing the figure handle or anything within the figure.
Just before using gco, set the HandleVisibility to "on" and then set it off again at the end of the function.
Example
% uifig is the handle to the figure
uifig.HandleVisibility = 'on';
h = gco();
uifig.HandleVisibility = 'off';
% You could leave it on but that risks other plotting functions
% having unintended access to the figure.
Alternatively you can set the handle visibility to "callback" so that it's accessible from callback functions.
You may need to make the figure & axes active after doing this; if so, see these instructions to a similar question.

14 Comments

I come back because when I get current point only xfront is correct. yfront has a value outside the axes YLim.
However the CurrentAxis is OK. My points (real and imaginary part of a complex number) are inside a unit circle. When I move a point on the x axis it is OK otherwise yfront being erroneous moving such a point fails.
Alain
What's xfront and yfront?
How are you "getting a point"? What's a point and how did it get on the plot?
How are you moving a point?
I think that there is a bug somewhere in my code whch is based on the following idea I have tested before.
function TestDrag()
hf=findobj('type','figure','tag','TestDrag');
if isempty(hf), hf=uifigure('tag','TestDrag','handlevisibility','on');end
ax=uiaxes('parent',hf,'XLim',[0 1],'YLim',[0 1]);
ax.Position(3:4)=.9*hf.Position(3:4);
cla;
line(.5,.5,'marker','o','markersize',5,'ButtonDownFcn',@(s,e) Drag(hf,ax,'start'),'parent',ax);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Drag(hf,ax,action)
switch action
case 'start'%
set(hf,'WindowButtonMotionFcn',@(s,e) Drag(hf,ax,'move'))
set(hf,'WindowButtonUpFcn',@(s,e) Drag(hf,ax,'stop'))
Drag(hf,ax,'move')
case 'move'
Cpoint=ax.CurrentPoint;
yf=Cpoint(3);
xf=Cpoint(1);
pt=gco;
pt.XData=xf;pt.YData=yf;
case 'stop'
set(hf,'WindowButtonMotionFcn','')
set(hf,'WindowButtonUpFcn','')
end
hello,
If the uiaxes parent is an uitab object the above code does not work yf (yfront) is incorrect!?
Here is my problem!
Alain
> If the uiaxes parent is an uitab object the above code does not work
That's not correct.
Here's a demo:
uif = uifigure();
uitg = uitabgroup(uif);
uit = uitab(uitg);
uia = uiaxes(uit);
h = plot(uia,magic(4),'o-');
uif.CurrentObject = h(1); % Sets current obj
uif.HandleVisibility = 'on';
gco
Result:
ans =
Line with properties:
Color: [0 0.447 0.741]
LineStyle: '-'
LineWidth: 0.5
Marker: 'o'
MarkerSize: 6
MarkerFaceColor: 'none'
XData: [1 2 3 4]
YData: [16 5 9 4]
ZData: [1×0 double]
Show all properties
gco/gca/gcf these functions are sloppy and I only use them when I'm quickly throwing something together.
If you do use them, supplying inputs makes them less sloppy. For example, if you want the current obj within a specific axes, gco(axisHandle).
If you have the figure handle, you can use fig.CurrentObject to get the current obj on the figure fig.
What happens in your code when there isn't a current object? gco will return an empty handle when there isn't a current obj or when the current obj isn't accessible due to handle visibility.
the content of gco is correct, in particular xdata and ydata are OK.
However when the mouse cursor moves the axes CurrentPoint is not good immediatly.
If I click on the point without moving xdata and CurrentPoint(1) are identical however CurrentPoint(3) is bad quite different of ydata.
You can verfy with the following test
function TestDrag(action)
% action ='wt' uifigure and axes within a uitab !! axes current point is bad !!
% action ='w*' uifigure and axes within uifigure OK
% action ='st' figure and axes within a uitab OK
% action ='s*' figure and axes within figure OK
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
hf=findobj('type','figure','tag','TestDrag');
if lower(action(1))=='w'
if isempty(hf), hf=uifigure('tag','TestDrag','handlevisibility','on');end
position=hf.Position;position(1:2)=[1 1];
clf;
if lower(action(2))=='t'
htabbed=uitabgroup(hf,'position',position);
htab=uitab(htabbed,'title','test');
else
htab=hf;
end
ax=uiaxes('parent',htab,'XLim',[0 1],'YLim',[0 1]);
else
if isempty(hf), hf=figure('tag','TestDrag','unit','pixel');end
position=hf.Position;position(1:2)=[1 1];
clf;
if lower(action(2))=='t'
htabbed=uitabgroup(hf,'unit','pixel','position',position);
htab=uitab(htabbed,'title','test');
else
htab=hf;
end
ax=axes('parent',htab,'XLim',[0 1],'YLim',[0 1],'unit','pixel');
end
cla;
line(.5,.5,'marker','o','markersize',5,'ButtonDownFcn',@(s,e) Drag(hf,ax,'start'),'parent',ax);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Drag(hf,ax,action)
switch action
case 'start'%
set(hf,'WindowButtonMotionFcn',@(s,e) Drag(hf,ax,'move'))
set(hf,'WindowButtonUpFcn',@(s,e) Drag(hf,ax,'stop'))
Drag(hf,ax,'move')
case 'move'
Cpoint=ax.CurrentPoint;
yf=Cpoint(3);
xf=Cpoint(1);
pt=gco;
pt.XData=xf;pt.YData=yf;
case 'stop'
set(hf,'WindowButtonMotionFcn','')
set(hf,'WindowButtonUpFcn','')
end
I still don't understand what you mean by moving a point.
What exactly are you moving? Why type of object? A marker plotted with plot(__) cannot be moved on the axes.
if you run my test program, you 'll see a point at (.5,.5). Now if you click down upon this point and drag it somewhere within the axes object you'll observe the point displacement and it keeps a new position when the mouse is released. It runs as expected except when the parent axes is a uitab within an ufigure.
I ran your demo and I understand what you're doing now.
I also updated it to include the uitab and when I drag the object there is a constant y-offset but the x coordinate doesn't seem to have a problem.
After some tinkering, I believe this is an error with the current point calculations from within Matlab code. If you read the documentation on the CurrentPoint property, you'll see that it changes when there is a WindowButtonMotionFcn assigned to the figure which is the case in your code. However, if you remove that and simplify the Drag callback function to merely display the current point, the error remains.
However, if you set the tab group units to normalize using uitg.Units='Normalized' where uitg is the tab group handle, the y error is greatly reduced and almost completely corrected. Unfortunately the position of the uitab group also slightly changes when the units are set to normalized.
For this reason, I believe it's an error in converting position between nested parents (fig>uitab group > uitab > axes).
I suggest you contact tech support if you want to pursue this > Contact Us - MATLAB & Simulink
% My reproduction of the problem
% function TestDrag()
hf=findobj('type','figure','tag','TestDrag');
if isempty(hf), hf=uifigure('tag','TestDrag','handlevisibility','on');end
uitg = uitabgroup(hf);
uit = uitab(uitg);
ax=uiaxes('parent',uit,'XLim',[0 1],'YLim',[0 1]);
ax.Position(3:4)= [150 150];
xlim(ax,[0,1])
ylim(ax,[0,1])
hold on
grid(ax,'on')
h =plot(ax, .5,.5,'marker','o','markersize',5,'ButtonDownFcn',@(s,e) Drag(hf,ax,'start'));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Drag(hf,ax,action)
switch action
case 'start'%
set(hf,'WindowButtonMotionFcn',@(s,e) Drag(hf,ax,'move'))
set(hf,'WindowButtonUpFcn',@(s,e) Drag(hf,ax,'stop'))
Drag(hf,ax,'move')
case 'move'
Cpoint=ax.CurrentPoint
yf=Cpoint(1,2);
xf=Cpoint(1,1);
pt=gco(ancestor(ax,'figure'));
pt.XData=xf;
pt.YData=yf;
case 'stop'
set(hf,'WindowButtonMotionFcn','')
set(hf,'WindowButtonUpFcn','')
end
end
"I suggest you contact tech support if you want to pursue this "
This is done
Thanks a lot
Alain
I'd be happy to hear what they have to say.
hello
The problem has been recognised as a bug by mathworks and has been fixed in MATLAB R2021a !! Good news!!
Alain

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!