Put arrow and its value in a plot

Hello there,
I want to show a row and its value in a plot. Please find attached the data. My intended plot should be like this:
load('data_ask_MLD')
figure;
plot(PTn,z);
set(gca,'ydir','reverse')
Thank you!

回答 (3 件)

Mathieu NOE
Mathieu NOE 2024 年 11 月 23 日

0 投票

hello
this is a simple example , based on the fex submission :
load('data_ask_MLD')
figure;
plot(PTn,z);
set(gca,'ydir','reverse')
% define which row for display
r = 100;
x = PTn(r);
y = z(r);
al = 1; % arrow length (in x direction)
arrow([x-al,y],[x,y]); % Fex : https://fr.mathworks.com/matlabcentral/fileexchange/278-arrow
text(x-4*al, y, ['MLD = ' sprintf('%0.5g', y)])

3 件のコメント

Adi Purwandana
Adi Purwandana 2024 年 11 月 25 日
編集済み: Adi Purwandana 2024 年 11 月 25 日
Great to know this function. Thank you @Mathieu NOE! but since I have lots of profiles, I need an automatically adjusted the MLD value instead of defining manually the r = 100.
Mathieu NOE
Mathieu NOE 2024 年 11 月 25 日
hello again
try this :
load('data_ask_MLD')
figure;
plot(PTn,z);
set(gca,'ydir','reverse')
% define which row for display
value = 24.7; % MLD value to display
[x,~] = find_zc(PTn,z,value);
y = value;
al = 1; % arrow length (in x direction)
arrow([x-al,y],[x,y]); % Fex : https://fr.mathworks.com/matlabcentral/fileexchange/278-arrow
text(x-3*al, y, ['MLD = ' sprintf('%0.5g', y)])
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ZxP,ZxN] = find_zc(x,y,threshold)
% find x values corresponding to y = threshold (like a zero crossing detector) :
% ZxP is x when signal slope is positive at the crossing point
% ZxN is x when signal slope is negative at the crossing point
% put data in rows
x = x(:);
y = y(:);
% positive slope "zero" crossing detection, using linear interpolation
y = y - threshold;
zci = @(data) find(diff(sign(data))>0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
ZxP = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
% negative slope "zero" crossing detection, using linear interpolation
zci = @(data) find(diff(sign(data))<0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
ZxN = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
end
Mathieu NOE
Mathieu NOE 2024 年 11 月 25 日
and if you need to plot more than one MLD value, you can use this modified code :
NB that I am not using interp1 because your profile is not monotonic everywhere , so interp1 may fail sometimes.
load('data_ask_MLD')
figure;
plot(PTn,z);
set(gca,'ydir','reverse')
% define which row for display
value = [24.7 33.1 54.7 78.9]; % MLD values to display
al = 1; % arrow length (in x direction)
for k = 1:numel(value)
[x,~] = find_zc(PTn,z,value(k));
x = x(1); % take the first value
arrow([x-al,value(k)],[x,value(k)]); % Fex : https://fr.mathworks.com/matlabcentral/fileexchange/278-arrow
text(x-3*al, value(k), ['MLD = ' sprintf('%0.5g', value(k))])
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ZxP,ZxN] = find_zc(x,y,threshold)
% find x values corresponding to y = threshold (like a zero crossing detector) :
% ZxP is x when signal slope is positive at the crossing point
% ZxN is x when signal slope is negative at the crossing point
% put data in rows
x = x(:);
y = y(:);
% positive slope "zero" crossing detection, using linear interpolation
y = y - threshold;
zci = @(data) find(diff(sign(data))>0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
ZxP = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
% negative slope "zero" crossing detection, using linear interpolation
zci = @(data) find(diff(sign(data))<0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
ZxN = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
end

サインインしてコメントする。

Pramil
Pramil 2024 年 11 月 23 日
編集済み: Pramil 2024 年 11 月 23 日

0 投票

Hi Adi,
You can use the "text" function available in MATLAB to create plot shown in your image. Here is the documentation link for the same for your reference:
And here is the updated code:
load('data_ask_MLD')
figure;
plot(PTn,z);
set(gca,'ydir','reverse')
[~, idx] = min(abs(z - MLD));
x_value = PTn(idx);
text(x_value, MLD, 'MLD = 24.7\rightarrow ','HorizontalAlignment','right');

1 件のコメント

Adi Purwandana
Adi Purwandana 2024 年 11 月 25 日
Thank you @Pramil; but since I have lots of profiles, I need an automatically adjusted the MLD value.

サインインしてコメントする。

Star Strider
Star Strider 2024 年 11 月 23 日
編集済み: Star Strider 2024 年 11 月 23 日

0 投票

The 'textarrow' coordinates have to adapt to the data and then correct for the reversed y-axis direction.
Try this —
load('data_ask_MLD')
figure;
plot(PTn,z);
set(gca,'ydir','reverse')
xlabel('PTn')
ylabel('z')
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
xl = xlim;
yl = ylim;
pos = gca().Position;
MLDval = 24.7;
PTnval = interp1(z, PTn, MLDval) % X-Coordinate Value (Derived From Data) Right End Of The Arrow
PTnval = 27.2905
zval = interp1(PTn, z, PTnval) % Y-Coordinate Value (Derived From Data)
zval = 24.7000
annotation('textarrow', xapf(PTnval+[-2.25 -0.25],pos,xl), 1-yapf([1 1]*zval,pos,yl), String=("MLD = "+MLDval)+" m ", HeadStyle='vback3')
EDIT — (23 Nov 2024 at 12:45)
Changed 'HeadStyle'.
.

4 件のコメント

Adi Purwandana
Adi Purwandana 2024 年 11 月 25 日
Thank you @Star Strider. Are you sure the arrow points the value 24.7? It should be point of MLD = 24.7 or z = y = 24.7.
Star Strider
Star Strider 2024 年 11 月 25 日
編集済み: Star Strider 2024 年 11 月 26 日
It was not originally obvious to me what axis ‘MLD’ refers to, since they are both quite similar. It plots correctly if the y-axis is not reversed. The absolute references do not change when the axis direction is reversed. (I consider that to be a bug.) Fudging an ‘ofst’ (offset) value is the best I can do in this instance.
load('data_ask_MLD')
figure;
plot(PTn,z);
set(gca,'ydir','reverse')
xlabel('PTn')
ylabel('z')
MLDval = [24.7; 100; 150];
for k = 1:numel(MLDval)
txt_arrow(z,PTn,MLDval(k),gca)
end
function txt_arrow(z,PTn,MLDval,gca)
PTnval = interp1(z, PTn, MLDval); % X-Coordinate Value (Derived From Data) Right End Of The Arrow
zval = interp1(PTn, z, PTnval); % Y-Coordinate Value (Derived From Data)
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
xl = xlim;
yl = ylim;
pos = gca().Position;
minz = yapf(min(z),pos,yl);
ofst = 1+minz/4;
annotation('textarrow', xapf(PTnval+[-2.25 -0.25],pos,xl), ofst-yapf([1 1]*zval,pos,yl), String=("MLD = "+MLDval)+" m ", HeadStyle='vback3')
end
Plotting more arrows would simply require running the annotation call in a loop, with appropriate values for ‘PTNval’ and ‘zval’. I wrote one here that seems to work.
EDIT — (25 Nov 2024 at 12:17)
I submitted a bug report on this problem this morning (‘Report a bug Case 07439706 created successfully’).
EDIT — (26 Nov 2024 at 11:57)
MathWorks corroborated my fiindings and was able to reproduce this behaviour. There may be a fix in a future release.
.
Adi Purwandana
Adi Purwandana 2024 年 11 月 26 日
Great! Thanks for let us know the update.
Star Strider
Star Strider 2024 年 11 月 26 日
My pleasure!
It appears that my ‘kludge’ fix is the best option just now. I have not checked to see if it might work in other instances, however I believe it is likely a ‘one-off’ that will not generalise to other situations.
My only consolation is that my code works correctly, and would continue to do so if the absolute references changed with the axis direction (and possibly axis scaling, however I have not experimented with it with a diifferent axiis scale).

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeLine Plots についてさらに検索

製品

リリース

R2022a

質問済み:

2024 年 11 月 23 日

コメント済み:

2024 年 11 月 26 日

Community Treasure Hunt

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

Start Hunting!

Translated by