How to find x value for a known y in array plot?

67 visualizaciones (últimos 30 días)
amoda
amoda el 7 de Ag. de 2022
Respondida: amoda el 14 de Ag. de 2022
I have to draw a plot based on a long matrix, which I did, after that I got the maximum of y value (max(y)) but I need the x value for the known y value y=0.8*max(y) THIS y value is not included in the matrix, so I can't use the Index of the maximum to get my x
and tried to apply the same code x(y==0.8*max(y)) but I get a 0x1 empty column vector.
Can anyone help me out? thanks in advance

Respuesta aceptada

Star Strider
Star Strider el 7 de Ag. de 2022
Possibly:
idx = find(diff(sign(y - 0.8*max(y))));
xvals = x(idx)
That should find the closest indices to all of them.
  2 comentarios
amoda
amoda el 10 de Ag. de 2022
Editada: amoda el 10 de Ag. de 2022
Hello Star Strider,
thank you for suggestion, I got a vector of 89 Indices and another with 89 corresponding x-values, but to be honest I am not sure how should I understand that, which one is the closest one to my desired x-value.
Star Strider
Star Strider el 10 de Ag. de 2022
Editada: Star Strider el 11 de Ag. de 2022
Without the data, it is difficult to determine that. It will be necessary to define a specific x-value to determine which is closest.
Example —
x = linspace(0, 20, 500); % Create Data
y = sin(2*pi*x) + cos(3*pi*x) - (x-10).^2/100; % Create Data
idx = find(diff(sign(y - 0.8*max(y))));
xvals = x(idx)
xvals = 1×12
5.2505 5.3307 7.2144 7.3747 9.2184 9.3788 11.2224 11.3828 13.2265 13.3467 15.2305 15.3106
x_desired = 10; % Define Target X-Value
[xabsdist,xidx] = min(abs(xvals - x_desired));
% idx(xidx)
% x(idx(xidx))
% y(idx(xidx))
fprintf(1,'Target Y-Value: %.3f\nClosest X-Value: %.3f\nCorresponding Y-Value: %.3f\nY-Distance |Desired-Actual|: %.3f\n', 0.8*max(y), x(idx(xidx)), y(idx(xidx)), abs(0.8*max(y)-y(idx(xidx))))
Target Y-Value: 1.517 Closest X-Value: 9.379 Corresponding Y-Value: 1.596 Y-Distance |Desired-Actual|: 0.080
figure
plot(x, y, 'DisplayName','Data')
hold on
plot(xvals, y(idx), 'ks', 'DisplayName','Closest Indices')
plot(x(idx(xidx)), y(idx(xidx)), 'rs', 'MarkerFaceColor','r', 'DisplayName','Closest X-Value')
yline(0.8*max(y), '--g', 'DisplayName','0.8\times y_{max} Reference')
xline(x_desired, '--r', 'DisplayName','Desired X-Value')
hold off
grid
legend('Location','best')
This uses synthetic data, however it should work for your actual data.
Make appropriate changes to get the result you want. (It is also possible to interpolate to get the exact x- and y-values rather than just using the indices.)
EDIT — (11 Aug 2022 at 1:00)
Added interpolation example.
Example —
tgt = 0.8*max(y);
L = numel(x);
for k = 1:numel(idx)
idxrng = max(1,idx(k)-1) : min(L,idx(k)+1);
xv(k) = interp1(y(idxrng), x(idxrng), tgt);
end
[xvabsdist,xvidx] = min(abs(xv - x_desired));
fprintf(1,'Closest X-Value: %.3f\nDistance |xv - x-desired|: %.3f\n', xv(xvidx),xvabsdist)
Closest X-Value: 9.386 Distance |xv - x-desired|: 0.614
figure
plot(x, y, 'DisplayName','Data')
hold on
plot(xv, ones(size(xv))*tgt, 'ks', 'DisplayName','Exact X-Values')
plot(xv(xvidx), tgt, 'rs', 'MarkerFaceColor','r', 'DisplayName','Closest X-Value')
yline(0.8*max(y), '--g', 'DisplayName','0.8\times y_{max} Reference')
xline(x_desired, '--r', 'DisplayName','Desired X-Value')
hold off
grid
legend('Location','best')
.

Iniciar sesión para comentar.

Más respuestas (4)

David Hill
David Hill el 7 de Ag. de 2022
[~,idx]=min(abs(y-.8*max(y)));%.8*max(y) is not part of the y-array, find the closest y-idx to that value
x(idx)
  1 comentario
amoda
amoda el 10 de Ag. de 2022
Hey David,
thanks a lot for your answer, unfortunately your code delivers no satisfiying result, because it gives me back, the corresponding X-value of max(y) which I used to get my y=0.8*max(y)

Iniciar sesión para comentar.


amoda
amoda el 10 de Ag. de 2022
meanwhile I tried to use the interpolation function Interp1, hoping it could deliver the best result, but I was wrong, I think it didnt work because I have only vectors and no functions.

Bruno Luong
Bruno Luong el 10 de Ag. de 2022
Editada: Bruno Luong el 10 de Ag. de 2022
*
x = linspace(-3,3);
Assuming your data are monotonic on the neighborhood of the max
y = exp(-x.^2);
[maxy, imax] = max(y);
yt = 0.8*maxy;
% left side
i1 = find(y<yt & 1:length(y)<imax, 1, 'last');
if isempty(i1)
error('no x found on the left side')
end
xl = interp1(y([i1 i1+1]), x([i1 i1+1]), yt)
xl = -0.4729
% right side
i2 = find(y<yt & 1:length(y)>=imax, 1, 'first');
if isempty(i2)
error('no x found on the right side')
end
xr = interp1(y([i2-1 i2]), x([i2-1 i2]), yt)
xr = 0.4729

amoda
amoda el 14 de Ag. de 2022
thank you all for your constructive answers, they all led me to find finally the most acceptable solution in my opinion:
yMax=max(y)
[idx,idy]=find(y==yMax)
Xcoresp=x(idx,idy)
y80=0.80*y
then I created linear vector which include my y80 value and apply the interpolation function
x1=linspace(x(1,1),Xcoresp,1000)
y1=linspace(y(1,1),yMax,1000)
xDesired=interp1(y1,x1,y80,'nearest')

Productos


Versión

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by