# how to normalize the image axis

16 views (last 30 days)
Niraj on 6 Dec 2012
hi, i need to plot a arrow in my image. I know that there is an inbuilt function in matlab called "annotation" which does the job, but it needs to normalize the axis in the range of [0 1]. Can any one help me in understanding how to normalize the image axis?

Jonathan Epperl on 6 Dec 2012
Edited: Jonathan Epperl on 6 Dec 2012
So it appears, that annontaion('arrow',... is kind of annoying to work with, since it is based on a coordinate system of the figure window, and not the axis. I think there are two ways to get what you want:
Either, go to the FEX and get one of the many scripts that create arrows for you.
Or, you can do some math with the coordinates. This code here is assuming that your y-axis is reversed, as the image command does it, and that both axes start at 0.
image(X);
axpos = get(gca,'Position'); % normalized position of the axis in the figure
xyl = [get(gca,'Xlim'); get(gca,'YLim')]*[-1 1]' % length of your axes
arrpos = [200 300; 150 250]; % the coords of the arrow in the units of you axes
% now figure out how your axis-unit coordinates translate to figure coordinates
arrposnorm = diag(axpos(3:4))*[arrpos(1,:)/xyl(1); (1-arrpos(2,:)/xyl(2))];
annotation('arrow',arrposnorm(1,:)+axpos(1),arrposnorm(2,:)+axpos(2),'Color','w')
I hope this is what you asked for, otherwise please give some more detail.
Jonathan Epperl on 7 Dec 2012
I can't tell from the picture, maybe your y-axis doesn't start at 0?
Zooming messes stuff up, too, since the arrow won't move relative to the figure at all.
Also, whatever you do to your axes, like titles, labels, legends, might move the axes relative to the figure, which would then result in a changed 'Position'. It thus might solve your problem, if you did everything you're doing with the axis, and only then run my code. If I run it on my machine, there is no problem:
s=subplot(2,2,2)
image(X)
axpos = get(s,'Position'); % normalized position of the axis in the figure
xyl = [get(s,'Xlim'); get(s,'YLim')]*[-1 1]' % length of your axes
arrpos = [200 300; 150 250]; % the coords of the arrow in the units of you axes
arrposnorm = diag(axpos(3:4))*[arrpos(1,:)/xyl(1); (1-arrpos(2,:)/xyl(2))];
annotation('arrow',arrposnorm(1,:)+axpos(1),arrposnorm(2,:)+axpos(2),'Color','w')
grid minor
If you're using subplots you can get their handles during creation
hs = subplot(2,1,2)
or so, that is more robust than using gca.
I agree with Image Analyst though, it's pretty pathetic that annotation relative to the axis coordinates is so hard. For what you want to do I would recommend a FEX function: http://www.mathworks.com/matlabcentral/fileexchange/278-arrow-m That is what I (along with probably most other people) am using for 2-D arrows.
If you're going to use arrow.m also note Kent Leung's comment, that might be relevant to you:
>>> 11 Jun 2012 Kent Leung
@Matthias, I had this problem too and just stumbled on a solution. (In fact, the problem for me was that the xlabel was disappearing.) To fix this I did:
ax1=subplot(2,1,1); [...] axes(ax1); arrow([x1 y1],[x2 y2]); arrow fixlimits;
I always do "fixlimits" just in case. The reason I tried this was because in the help file: "You may want to execute AXIS(AXIS) before calling arrow so it doesn't change the axes on you; arrow determines the sizes of arrow components BEFORE the arrow is plotted, so if arrow changes axis limits, arrows may be malformed."
It's not obvious that this fixed the subplot resizing problem, but it worked! <<<