Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

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
share|improve this question

2 Answers 2

up vote 1 down vote accepted

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
share|improve this answer
1  
You can get the index by calling with two output parameters: $[value,index]=\max(array)$. –  Daryl Apr 8 '13 at 11:50
    
@Daryl: Thanks! I did not know that. –  sonystarmap Apr 8 '13 at 11:51
    
@macydanim: This is a great help. When I replace your signal with the data I have though, it doesn't hit the points on the 50%/90% line. I'll update the question with my dataset. –  Carl Apr 8 '13 at 12:31
    
@Carl, yeah that is due to the problem that the jumps between your data are large. In my example this is not the case. Therefore, the point above and below the 90% line is exactly the maximum and a value far below. I think you need to interpolate in this case, give me some time. –  sonystarmap Apr 8 '13 at 12:38
    
@Carl see the last edit, this works for me, using your date –  sonystarmap Apr 8 '13 at 12:45

You can find the maximum point using the $\tt max$ and $\tt find$ commands in Matlab:

$\tt ymax = max(y);$

$\tt xmax = x(find(y == ymax));$

The other points do not exist in your data, i.e. there is probably no point that hits exactly the 20% line or the 50% line. For these you would need to interpolate.

share|improve this answer
    
That Matt. That's a useful start for me. Much appreciated. How would I go about getting Matlab to approximate a gaussian curve to fit the signal? From that I should be able to interpolate the 20% and 50% points. –  Carl Apr 8 '13 at 11:28
1  
$xmax$ would not be the x-position of the maximum, but the ID of the element of vector $x$ where the maximum occurs. So it should rather be xmax = x(find(y==ymax)) –  sonystarmap Apr 8 '13 at 11:30
    
@Carl You can also get the index of the maximum value of an array by $[value,index] =\max(array)$. –  Daryl Apr 8 '13 at 11:49
    
Thanks macydanim for pointing out my mistake, you are perfectly right of course. –  Matt L. Apr 8 '13 at 12:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.