필터 지우기
필터 지우기

Why aren't the first and last peaks detected using findpeaks()?

조회 수: 27 (최근 30일)
FsC
FsC 2022년 10월 30일
댓글: FsC 2022년 12월 8일
I am using the findpeaks() function to detect any peaks in a vector that are greater than a defined threshold (>10% max peak).
I use the following find peaks code but find that the first or last peaks tend to be missed.
% find peaks in vec1 data using find peaks
thresh = .1 * max(dt);
[pks,vec1locs] = findpeaks(vec1, 'MinPeakProminence',thresh);
%plot vector and detected peaks
plot(vec1)
hold on
plot(vec1locs,pks,'or')
Below is the plot of the detected peaks and it didn't detect the last peak.
If I apply the same code with a different vector (vec2), it does not detect the first peak.
I've attached the data vectors if anyone would like to try. Are you seeing the same issue? Why is this happening and how can this be fixed?
Thank you!

채택된 답변

Mike Croucher
Mike Croucher 2022년 10월 30일
For vec1, the reason is that the peak is also the last data point and so is intentionally exlcuded. The findpeaks documentation says "Non-Inf signal endpoints are excluded."
For vec2, the issue is thresholding. Your threshold is expressed in terms of dt but you haven't mentioned how this is defined. So, I guessed and put
thresh = 0.1*max(vec2)
which gives around 0.0021, reproducing your second plot including the fact that the first peak is not detected.
Let's compare a peak that is detected (at element 39) with the one that is not (at element 11). The peak at element 39 'sticks out more' compared to its neighbours.
disp('peak at 11')
fprintf("the 10th element is %f\n",vec2(10))
fprintf("the 11th element is %f\n",vec2(11))
fprintf("the 12th element is %f\n",vec2(12))
disp('Peak at 39')
fprintf("the 38th element is %f\n",vec2(38))
fprintf("the 39th element is %f\n",vec2(39))
fprintf("the 40th element is %f\n",vec2(40))
gives
peak at 11
the 10th element is 0.016000
the 11th element is 0.018000
the 12th element is 0.016000
Peak at 39
the 38th element is 0.015000
the 39th element is 0.018000
the 40th element is 0.015000
The threshold I used was 0.0021. Lowering it a little to 0.0020 unfortunately detects too many peaks
I'm not an expert in how to best use findpeaks but one way of getting what you want is to lower the threshold a little and set a minimum peak height. Like this:
load vec2.mat
%thresh = 0.1*max(vec2);
thresh = 0.0019
[pks,vec2locs] = findpeaks(vec2, 'MinPeakProminence',thresh,'MinPeakHeight',0.0175);
%plot vector and detected peaks
plot(vec2)
hold on
plot(vec2locs,pks,'or')
hold off
This gives

추가 답변 (1개)

Image Analyst
Image Analyst 2022년 10월 30일
Maybe because you don't have a point on the other side so it doesn't know if it's a peak or just a point on the side of a larger, missing peak.
  댓글 수: 1
FsC
FsC 2022년 10월 30일
That could make sense for vec1 but why is it not detecting the first peak for vec 2?

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Descriptive Statistics에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by