How to detect a peak from a 2D graph

71 views (last 30 days)
Evans Gyan
Evans Gyan on 27 Apr 2019
Commented: Star Strider on 29 Apr 2019
I want to find the x, and y values that makes up the peak. I have attach the image for better clarification. I tried to use the codes below to obtain the values. There are three peaks but i get extra peaks from my code. Besides, i have trouble finding the rigth X, and Y values that makes up the peaks. Your assistance is highly appreciated.
tt1=0:1:90;
tt2=0:1:90;
figure(1)
PPM=10*log10(PPM);
figure(1) %???
mesh(tt1,tt2,PPM)
%axis([0,90,0,90])
xlabel('x')
ylabel('y')
[pks,locs] = findpeaks(PPM);
angs = tt1(locs)';
angs = tt2(locs)';
untitled.png
  1 Comment
Rik
Rik on 27 Apr 2019
I don't have the required toolbox, so I can't test this myself, but have you tried the other inputs and output of findpeaks? Specifically the prominence? That sounds like something you could try. If you are certain there will always be exactly 3 relevant peaks, you could even use it to select the 3 peaks with the highest prominence.

Sign in to comment.

Answers (1)

Star Strider
Star Strider on 27 Apr 2019
Try this:
[pks,locs] = findpeaks(PPM(:));
[r,c] = ind2sub(size(PPM), locs);
See my example code below for guidance on the rest of it. My guess is that you would index into ‘tt1’ and ‘tt2’ to plot the peaks. I can’t test that without your code.
Using synthetic data to test this idea, it can work:
v = linspace(-10, 10, 25);
[X,Y] = ndgrid(v);
Z = sin(5*pi*X) + cos(5*pi*Y);
[pks,locs] = findpeaks(Z(:), 'MinPeakHeight',1, 'MinPeakProminence',2.1);
[r,c] = ind2sub(size(Z), locs);
figure
mesh(X, Y, Z)
hold on
plot3(X(r,c), Y(r,c), pks, '^r')
hold off
grid on
Make appropriate changes to get the result you want with your data.
I never previously considered using findpeaks for a 3D problem.
  2 Comments
Evans Gyan
Evans Gyan on 29 Apr 2019
hello, I tried your suggestion but am still having some difficulties. For further clarification
Hope this will make it clearer.
GNA = randn(36);
dd =0:5;
tt1=0:1:90; tt2=0:1:90;
for pop1=1:length(tt1)
for pop2=1:length(tt2)
A1=exp(-0.0001*(2*pi)*dd'*sin(tt1(pop1)/180*pi));
B1=exp(-0.0001*(2*pi)*dd'*sin(tt1(pop2)/180*pi));
C1=kron(A1,B1)
PPM(pop1,pop2)=1/(C1'*GNA'*C1);
end
end
PPM=10*log10(PPM);
figure(1) %???
mesh(tt1,tt2,PPM)
%axis([0,90,0,90])
xlabel('x') ; ylabel('y') ;
[pks,locs] = findpeaks(PPM(:))%, 'MinPeakHeight',0, 'MinPeakProminence',2.1)
angs = tt1(locs);
angs = tt2(locs);
From the graph, the obtained peaks, I want to fetech its value from tt1 and tt2.
Star Strider
Star Strider on 29 Apr 2019
The ‘PPM’ matrix is complex, so you either have to take the real value or the absolute value of it in the findpeaks and mesh calls.
The problem is that unlike the plot image you posted, your function also doesn’t have any actual peaks, so the results of findpeaks are at best ambiguous. Even when I remove the dB conversion (and with it the complex numbers), there are no discernable peaks.
I would amend the findpeaks call to:
[pks,locs] = findpeaks(real(PPM(:)), 'MinPeakHeight',-18, 'MinPeakProminence',0.001);
and add after your findpeaks call:
[r,c] = ind2sub(size(PPM), locs);
[X,Y] = meshgrid(tt1,tt2);
figure(2) %???
mesh(X,Y,abs(PPM))
hold on
plot3(X(r,c), Y(r,c), pks, '^r')
hold off
grid on
This idea worked with the function I posted (that actually has peaks).
If you have a function with peaks, we can revisit this. Make appropriate changes to the findpeaks name-value pair arguments to get good discrimination of any peaks that appear.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!