How do use the annotation function to annotate specific x-values on my graph?
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
I want to use the annotation function to show x-min and x-max values on my graph. Here is my code:
x = [0:300];
lda = 300;
uhat = 10;
k = ((2*pi)/(lda));
phi1 = 0;
advection1 = uhat*((cos((k*x)-(phi1))));
xmaxadvection1 = ((0)+phi1)/(k);
xminadvection1 = ((pi)+phi1)/(k);
figure(1)
plot(x,advection1)
xlabel('x (km)')
ylabel('advection')

Accepted Answer
Star Strider
on 30 Sep 2023
I wrote a couple anonymous functions recently to transform (x,y) coordinates to normalised coordinates for just this purpose.
Try this —
x = [0:300];
lda = 300;
uhat = 10;
k = ((2*pi)/(lda));
phi1 = 0;
advection1 = uhat*((cos((k*x)-(phi1))));
xmaxadvection1 = ((0)+phi1)/(k);
xminadvection1 = ((pi)+phi1)/(k);
figure(1)
plot(x,advection1)
xlabel('x (km)')
ylabel('advection')
pos = gca().Position;
xapf = @(x,pos,xl) pos(3)*(x-min(xl))/diff(xl)+pos(1); % 'x' Annotation Position Function
yapf = @(y,pos,yl) pos(4)*(y-min(yl))/diff(yl)+pos(2); % 'y' Annotation Position Function
annotation('textarrow', xapf([15 0]+xmaxadvection1,pos,xlim), yapf([-8 -10],pos,ylim), 'String','x_{max}')
annotation('textarrow', xapf([1 1]*xminadvection1,pos,xlim), yapf([-8 -10],pos,ylim), 'String','x_{min}')

The first arguments to the functions are the appropriate vectors that define the arrows, the second is the axis position vector, and the third are the axis limits. (Making them more intuitive is difficult.) Make appropriate changes to get the result you want.
.
6 Comments
Matthew
on 30 Sep 2023
Is there anyway to move the xmax annotation to the point (0,10) or this is that really tricky?
Not tricky at all!
x = [0:300];
lda = 300;
uhat = 10;
k = ((2*pi)/(lda));
phi1 = 0;
advection1 = uhat*((cos((k*x)-(phi1))));
xmaxadvection1 = ((0)+phi1)/(k);
xminadvection1 = ((pi)+phi1)/(k);
figure(1)
plot(x,advection1)
xlabel('x (km)')
ylabel('advection')
pos = gca().Position;
xapf = @(x,pos,xl) pos(3)*(x-min(xl))/diff(xl)+pos(1); % 'x' Annotation Position Function
yapf = @(y,pos,yl) pos(4)*(y-min(yl))/diff(yl)+pos(2); % 'y' Annotation Position Function
annotation('textarrow', xapf([15 0]+xmaxadvection1,pos,xlim), yapf([8 10],pos,ylim), 'String','x_{max}')
annotation('textarrow', xapf([1 1]*xminadvection1,pos,xlim), yapf([-8 -10],pos,ylim), 'String','x_{min}')

It only requires changing the first argument to ‘yapf’ in the appropriate annotation call, in thie instance changing the signs. (In the interest of clarity, I duplicated everything here, with that one exception. The first element of the two-element vectors is where the annotation arrow begins, and the second is where it ends, also describing the direction of the arrow. This corresponds to the conventions in the annotation documentation.)
.
Thanks for the help. The only other question I have is if I run this code how would I get the annotation on xmin and xmax on this plot. I'm still confused on how to apply the code you gave me to other codes. Here is my code for that one:
x = [0:300];
lda = 300;
k = ((2*pi)/(lda));
uhat = 10;
phi2 = pi/4;
advection2 = (uhat)*(k)*(cos((k*x)-(phi2)));
xminadv2 = ((pi)+phi2)/(k);
xmaxadv2 = ((0)+phi2)/(k);
figure(1)
plot(x,advection2)

Star Strider
on 30 Sep 2023
Edited: Star Strider
on 30 Sep 2023
As always, my pleasure!
Even with my transformation (mapping) functions, annotations are not straightforward.
x = [0:300];
lda = 300;
k = ((2*pi)/(lda));
uhat = 10;
phi2 = pi/4;
advection2 = (uhat)*(k)*(cos((k*x)-(phi2)));
xminadv2 = ((pi)+phi2)/(k);
xmaxadv2 = ((0)+phi2)/(k);
figure(1)
plot(x,advection2)
ymaxadv2 = interp1(x, advection2, xmaxadv2); % Interpolate To Determine Coordinate Value
yminadv2 = interp1(x, advection2, xminadv2); % Interpolate To Determine Coordinate Value
pos = gca().Position;
xapf = @(x,pos,xl) pos(3)*(x-min(xl))/diff(xl)+pos(1); % 'x' Annotation Position Function
yapf = @(y,pos,yl) pos(4)*(y-min(yl))/diff(yl)+pos(2); % 'y' Annotation Position Function
annotation('textarrow', xapf([0 0]+xmaxadv2,pos,xlim), yapf([-0.05 0]+ymaxadv2,pos,ylim), 'String','x_{max}')
annotation('textarrow', xapf([0 0]+xminadv2,pos,xlim), yapf([0.05 0]+yminadv2,pos,ylim), 'String','x_{min}')

The most notable change from the previous plots are that instead of having the y-values defined (they were the axis limits before), this time it is necessary to interpolate (using interp1) to find them. I added those steps here.
In this instance, the ‘x’ coordinates are the same (that is not required, however it seems that arrows that are straight up-down work best here), so the first argument to ‘xapf’ in both instances is [0 0] added to the ‘x’ coordinate. The first arguments to ‘yapf’ are [-0.05 0] added to the ‘ymaxadv2’ value so that its arrow ascends, and [0.05 0] added to ‘yminadv2’ so that its arrow descends.
In each situation, the first value of the two-element vector is where the arrow starts, and the second is where it ends. There is nothing particularly immutable about the ‘0.05’ value, and it can be anything you want so long as it gives the result you want. (I chose it arbitrarily, given the y-axis scale values.)
My functions map the intuitive (x,y) coordinates to the normalised coordinates required by the annotation functions. Unfortuantely, annotation functions are still themselves not quite intuitive.
EDIT — (30 Sep 2023 at 19:13)
Minor change (adding the two-element vectors to the constants in the first arguments to ‘xapf’ and ‘yapf’ in every instance) to make the code consistent. Results unchanged.
.
Sorry about this but I have one more question when using this annotation function. I am getting errors that X and Y values should be between 0 and 1. How would I do it with this code? Thanks again.
x = [0:300]*10^3;
That = 7.5; % in Kelvin
lda = 300*10^3; % in km
k = ((2*pi)/(lda)); % finding k
uhat = 10; % in m/s
phi1 = 0;
phi2 = pi/4;
phi3 = pi/2;
advection1 = -((uhat)*sin((k.*x)-phi1))*(-That)*(k).*(cos(k*x));
lbda2 = 300;
k1 = ((2*pi)/(lbda2)); % in km
xmaxadvection1 = ((phi1)/(2*k1)) - ((pi)/(4*k1)) + ((pi)/(2*k1));
xminadvection1 = ((phi1)/(2*k1)) - ((pi)/(4*k1)) + ((pi*2)/(2*k1));
xmaxadvection_1 = ((phi1)/(2*k1)) - ((pi)/(4*k1)) + ((pi*3)/(2*k1));
xminadvection_1 = ((phi1)/(2*k1)) - ((pi)/(4*k1)) + ((pi*4)/(2*k1));
figure(3)
plot(x/1000,advection1)

No worries! The annotation funcitons are not intuitive, and (unfortunately) neither are my functions to transform the (xy) coordinates to normalised values to work with them.
Until I looked closer, I did not realise that you were dividing ‘x’ by 1000 in the plot, so I was getting some anomalous values for ‘yxmax’ and ‘yxmin’ (interpolation to find the corresponding y-values for the x-values). I defined ‘ofst’ as one-tenth the ylim difference, governing the lengths of the arrows. Change that if you want to.
Also, if you want different names for the annotations (other than
and
) you can put those into a cell array or a string array and then subscript them appropriately as the value in the 'String' name-value pair in the annotation calls in the loop that plots them. No other changes should be necessary to get them to display correctly.
) you can put those into a cell array or a string array and then subscript them appropriately as the value in the 'String' name-value pair in the annotation calls in the loop that plots them. No other changes should be necessary to get them to display correctly. This should work —
x = [0:300]*10^3;
That = 7.5; % in Kelvin
lda = 300*10^3; % in km
k = ((2*pi)/(lda)); % finding k
uhat = 10; % in m/s
phi1 = 0;
phi2 = pi/4;
phi3 = pi/2;
advection1 = -((uhat)*sin((k.*x)-phi1))*(-That)*(k).*(cos(k*x));
lbda2 = 300;
k1 = ((2*pi)/(lbda2)); % in km
xmaxadvection1 = ((phi1)/(2*k1)) - ((pi)/(4*k1)) + ((pi)/(2*k1));
xminadvection1 = ((phi1)/(2*k1)) - ((pi)/(4*k1)) + ((pi*2)/(2*k1));
xmaxadvection_1 = ((phi1)/(2*k1)) - ((pi)/(4*k1)) + ((pi*3)/(2*k1));
xminadvection_1 = ((phi1)/(2*k1)) - ((pi)/(4*k1)) + ((pi*4)/(2*k1));
xmax = [xmaxadvection1; xmaxadvection_1]; % Combine Into One Vector For Efficiency
yxmax = interp1(x/1000, advection1,xmax); % Interpolate To Find 'y' Coordinate
xmin = [xminadvection1; xminadvection_1];
yxmin = interp1(x/1000, advection1,xmin);
figure(3)
plot(x/1000,advection1)
pos = gca().Position;
xapf = @(x,pos,xl) pos(3)*(x-min(xl))/diff(xl)+pos(1); % 'x' Annotation Position Function
yapf = @(y,pos,yl) pos(4)*(y-min(yl))/diff(yl)+pos(2); % 'y' Annotation Position Function
ofst = diff(ylim)/10; % Used In 'text' Calls
for k = 1:numel(xmax)
annotation('textarrow', xapf([0 0]+xmax(k),pos,xlim), yapf(-[ofst 0]+yxmax(k),pos,ylim), 'String','x_{max}')
end
for k = 1:numel(xmin)
annotation('textarrow', xapf([0 0]+xmin(k),pos,xlim), yapf([ofst 0]+yxmin(k),pos,ylim), 'String','x_{min}')
end

.
More Answers (0)
Categories
Find more on Labels and Annotations in Help Center and File Exchange
Products
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)