[Math] Finding points along a plot in Matlab

MATLAB

I have the following plot and a file of the data which creates that plot. I would like to have Matlab find the following points for me:

  1. [y,x] for peak noted by the 100% line
  2. [x] for where the plot crosses the y=0 line
  3. [x] for where y is 50% and 20% of the peak found in part 1.

Are there any add-on tools or packages which people are aware of which can help me accomplish this? I need to do this for a collection of plots so something reasonably automated would be ideal.

I can certainly do the programming and calculation parts in Matlab, it's just a matter of being able to load in the data file, matching it to a curve or function, and find the various [x,y] co-ordinates.

Data plot

Update
Here's a sample dataset I am testing with:

x-values        y-values
-9.90056E+01    4.08949E-03
-8.58224E+01   -2.52083E-02
-7.26381E+01    3.39976E-02
-5.94526E+01   -6.90023E-02
-4.62659E+01    8.37428E-02
-3.30781E+01   -1.74139E-01
-1.98891E+01    2.09784E-01
-6.69894E+00    7.43248E-01
6.49238E+00    6.08539E-02
1.96849E+01   -1.64983E-01
3.28785E+01    8.34376E-02
4.60733E+01   -6.71712E-02
5.92692E+01    7.21458E-02
7.24664E+01   -2.20038E-02
8.56646E+01    3.44554E-02
9.88641E+01   -9.46063E-04

Best Answer

Maybe this code can help you:

function mse


x = linspace(0,10,100);
y = sin(x)+x-(x/5).^2;
hold off

plot(x,y)

yMax = max(y);
xMax = x(find(y==yMax));

hold on
plot(xMax,yMax,'*g')



y90 = yMax*0.9;
plot(x,y90,'-k')


for i=2:length(x)
    if y(i-1)<=y90 && y(i)>=y90 || y(i-1)>=y90 && y(i)<=y90
        plot(x(i),y(i),'og')
        plot(x(i-1),y(i-1),'og')

    end
end


y50 = yMax*0.5;
plot(x,y50,'-k')
for i=2:length(x)
    if y(i-1)<=y50 && y(i)>=y50 || y(i-1)>=y50 && y(i)<=y50
        plot(x(i),y(i),'og')
        plot(x(i-1),y(i-1),'og')

    end
end
end

Here $x,y$ are my data. Finding the maximum is easy, but for the 90% or 50% values I iterated through the data. As we do not have continous data we check, whether the 90% or 50% values lies between to points. The result is shown below. If you only want to highlight a single point instead of the two you could perform some (linear) interpolation. enter image description here

EDIT: This would highlight all points that match the X% criteria. If you only want to highlight the closest points to the maximum, you could change the loop to something like

 for i=find(y==ymax):length(x)

Which finds the point on the right and for the left side

 for i=find(y==ymax):-1:length(x)

To mark only one point you could use a break command.

EDIT2: The following code performs the same thing as the for loops, but it is shorter.

y90 = yMax*0.9;
xId= find(diff(sign(y-y90))~=0);
plot(x(xId),y(xId),'*k')
plot(x(xId+1),y(xId+1),'*k')

EDIT3: For your date you need to interpolate between the two values. Replace the loop with something like

for i=2:length(x)
    if y(i-1)<=y90 && y(i)>=y90 || y(i-1)>=y90 && y(i)<=y90
        plot(x(i),y(i),'og')
        plot(x(i-1),y(i-1),'og')

        xl = x(i-1);
        yl = y(i-1);
        xr = x(i);
        yr = y(i);

        xMid  = (y90-yl)*(xr-xl)/(yr-yl)+xl;
        plot(xMid,y90,'or');

    end
end
Related Question