findpeaks
Find local maxima
Syntax
Description
returns a vector with the local maxima (peaks) of the input signal vector,
pks
= findpeaks(y
)y
. A local peak is a data
sample that is either larger than its two neighboring samples or is equal to
Inf
. The peaks are output in order of occurrence.
Non-Inf
signal endpoints are excluded. If a peak is flat,
the function returns only the point with the lowest index.
[___] = findpeaks(___,
specifies options using name-value arguments in addition to any of the input
arguments in previous syntaxes.Name,Value
)
findpeaks(___)
without output
arguments plots the signal and overlays the peak values.
Examples
Find Peaks in a Vector
Define a vector with three peaks and plot it.
data = [25 8 15 5 6 10 10 3 1 20 7]; plot(data)
Find the local maxima. The peaks are output in order of occurrence. The first sample is not included despite being the maximum. For the flat peak, the function returns only the point with lowest index.
pks = findpeaks(data)
pks = 1×3
15 10 20
Use findpeaks
without output arguments to display the peaks.
findpeaks(data)
Find Peaks and Their Locations
Create a signal that consists of a sum of bell curves. Specify the location, height, and width of each curve.
x = linspace(0,1,1000); Pos = [1 2 3 5 7 8]/10; Hgt = [3 4 4 2 2 3]; Wdt = [2 6 3 3 4 6]/100; for n = 1:length(Pos) Gauss(n,:) = Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2); end PeakSig = sum(Gauss);
Plot the individual curves and their sum.
plot(x,Gauss,'--',x,PeakSig)
Use findpeaks
with default settings to find the peaks of the signal and their locations.
[pks,locs] = findpeaks(PeakSig,x);
Plot the peaks using findpeaks
and label them.
findpeaks(PeakSig,x) text(locs+.02,pks,num2str((1:numel(pks))'))
Sort the peaks from tallest to shortest.
[psor,lsor] = findpeaks(PeakSig,x,'SortStr','descend'); findpeaks(PeakSig,x) text(lsor+.02,psor,num2str((1:numel(psor))'))
Peak Prominences
Create a signal that consists of a sum of bell curves riding on a full period of a cosine. Specify the location, height, and width of each curve.
x = linspace(0,1,1000); base = 4*cos(2*pi*x); Pos = [1 2 3 5 7 8]/10; Hgt = [3 7 5 5 4 5]; Wdt = [1 3 3 4 2 3]/100; for n = 1:length(Pos) Gauss(n,:) = Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2); end PeakSig = sum(Gauss)+base;
Plot the individual curves and their sum.
plot(x,Gauss,'--',x,PeakSig,x,base)
Use findpeaks
to locate and plot the peaks that have a prominence of at least 4.
findpeaks(PeakSig,x,'MinPeakProminence',4,'Annotate','extents')
The highest and lowest peaks are the only ones that satisfy the condition.
Display the prominences and the widths at half prominence of all the peaks.
[pks,locs,widths,proms] = findpeaks(PeakSig,x); widths
widths = 1×6
0.0154 0.0431 0.0377 0.0625 0.0274 0.0409
proms
proms = 1×6
2.6816 5.5773 3.1448 4.4171 2.9191 3.6363
Find Peaks with Minimum Separation
Sunspots are a cyclic phenomenon. Their number is known to peak roughly every 11 years.
Load the file sunspot.dat
, which contains the average number of sunspots observed every year from 1700 to 1987. Find and plot the maxima.
load sunspot.dat
year = sunspot(:,1);
avSpots = sunspot(:,2);
findpeaks(avSpots,year)
Improve your estimate of the cycle duration by ignoring peaks that are very close to each other. Find and plot the peaks again, but now restrict the acceptable peak-to-peak separations to values greater than six years.
findpeaks(avSpots,year,'MinPeakDistance',6)
Use the peak locations returned by findpeaks
to compute the mean interval between maxima.
[pks,locs] = findpeaks(avSpots,year,'MinPeakDistance',6);
meanCycle = mean(diff(locs))
meanCycle = 10.9600
Create a datetime
array using the year data. Assume the sunspots were counted every year on March 20th, close to the vernal equinox. Find the peak sunspot years. Use the years
function to specify the minimum peak separation as a duration
.
ty = datetime(year,3,20); [pk,lk] = findpeaks(avSpots,ty,'MinPeakDistance',years(6)); plot(ty,avSpots,lk,pk,'o')
Compute the mean sunspot cycle using datetime
functionality.
dttmCycle = years(mean(diff(lk)))
dttmCycle = 10.9600
Create a timetable with the data. Specify the time variable in years. Plot the data. Show the last five entries of the timetable.
TT = timetable(years(year),avSpots); plot(TT.Time,TT.Variables)
entries = TT(end-4:end,:)
entries=5×1 timetable
Time avSpots
________ _______
1983 yrs 66.6
1984 yrs 45.9
1985 yrs 17.9
1986 yrs 13.4
1987 yrs 29.3
Constrain Peak Features
Load an audio signal sampled at 7418 Hz. Select 200 samples.
load mtlb
select = mtlb(1001:1200);
Find the peaks that are separated by at least 5 ms.
To apply this constraint, findpeaks
chooses the tallest peak in the signal and eliminates all peaks within 5 ms of it. The function then repeats the procedure for the tallest remaining peak and iterates until it runs out of peaks to consider.
findpeaks(select,Fs,'MinPeakDistance',0.005)
Find the peaks that have an amplitude of at least 1 V.
findpeaks(select,Fs,'MinPeakHeight',1)
Find the peaks that are at least 1 V higher than their neighboring samples.
findpeaks(select,Fs,'Threshold',1)
Find the peaks that drop at least 1 V on either side before the signal attains a higher value.
findpeaks(select,Fs,'MinPeakProminence',1)
Peaks of Saturated Signal
Sensors can return clipped readings if the data are larger than a given saturation point. You can choose to disregard these peaks as meaningless or incorporate them to your analysis.
Generate a signal that consists of a product of trigonometric functions of frequencies 5 Hz and 3 Hz embedded in white Gaussian noise of variance 0.1². The signal is sampled for one second at a rate of 100 Hz. Reset the random number generator for reproducible results.
rng default
fs = 1e2;
t = 0:1/fs:1-1/fs;
s = sin(2*pi*5*t).*sin(2*pi*3*t)+randn(size(t))/10;
Simulate a saturated measurement by truncating every reading that is greater than a specified bound of 0.32. Plot the saturated signal.
bnd = 0.32;
s(s>bnd) = bnd;
plot(t,s)
xlabel('Time (s)')
Locate the peaks of the signal. findpeaks
reports only the rising edge of each flat peak.
[pk,lc] = findpeaks(s,t); hold on plot(lc,pk,'x')
Use the 'Threshold'
name-value pair to exclude the flat peaks. Require a minimum amplitude difference of between a peak and its neighbors.
[pkt,lct] = findpeaks(s,t,'Threshold',1e-4); plot(lct,pkt,'o','MarkerSize',12)
Determine Peak Widths
Create a signal that consists of a sum of bell curves. Specify the location, height, and width of each curve.
x = linspace(0,1,1000); Pos = [1 2 3 5 7 8]/10; Hgt = [4 4 2 2 2 3]; Wdt = [3 8 4 3 4 6]/100; for n = 1:length(Pos) Gauss(n,:) = Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2); end PeakSig = sum(Gauss);
Plot the individual curves and their sum.
plot(x,Gauss,'--',x,PeakSig)
grid
Measure the widths of the peaks using the half prominence as reference.
findpeaks(PeakSig,x,'Annotate','extents')
Measure the widths again, this time using the half height as reference.
findpeaks(PeakSig,x,'Annotate','extents','WidthReference','halfheight') title('Signal Peak Widths')
Nonlinear Least Squares Peak Refinement
Obtain a refined peak location estimate for the main two peaks in a signal using the nonlinear least squares method with a sinc function kernel.
Generate Signal
Radar pulse compression of a linear FM waveform produces a sinc-shaped spectrum, where the peaks frequency locations are proportional to the distance between the radar and the detected object. You can first estimate the peak locations and amplitudes with findpeaks
and then enhance your estimates with refinepeaks
. This example recreates a noiseless pulse-compression signal, finds and refines the signal peak amplitudes and locations.
Generate a signal composed of two sinc-shaped waveforms with peaks of 1 and 1.5 at 4.76 kHz and 35.8 kHz, respectively. The frequency spacing is 2.5 Hz.
aTarget = [1 1.5]; fTarget = 1e3*[4.76 35.8]; freqkHzFull = (0:0.0025:50)'; waveFull = abs(sinc([1 0.5].*(freqkHzFull-fTarget/1e3)))*aTarget';
Downsample the signal by a factor of 200 so the frequency spacing between samples is 0.5 kHz. This example refines the amplitude and location estimates of the downsampled signal peaks and compares the improved estimates to the values in the original signals.
freq = downsample(freqkHzFull,200); wave = downsample(waveFull,200); plot(freqkHzFull,waveFull,freq,wave,"*") legend(["Full signal" "Selected samples"],Location="northwest") xlabel("Frequency (kHz)") ylabel("Magnitude")
Refine Peaks Using Nonlinear Least Squares
Use findpeaks
to make initial estimates of the amplitudes, locations, and half-height widths of the two highest peaks of the signal.
[PV,PL,PW] = findpeaks(wave,NPeaks=2, ... SortStr="descend",WidthReference="halfheight");
Use refinepeaks
to enhance the peak estimation using the nonlinear least squares (NLS) method. Specify the frequency points of the signal and the peak widths. The peak values are significantly closer to the expected values of 1.5 and 1 while the frequency locations approximate well to 35.8 kHz and 4.76 kHz, respectively.
LW = max(PW,2);
[Ypk,Xpk] = refinepeaks(wave,PL,freq,Method="NLS",LobeWidth=LW)
Ypk = 2×1
1.5063
1.0163
Xpk = 2×1
35.8001
4.7628
Plot the amplitudes of refined peaks on the y-axis and the updated peak locations compared with the initial peak estimates on the x-axis. The two initially estimated peaks and their two surrounding samples are separated 0.5 kHz between each other. The refined peaks, shown with filled circles, indicate a repositioning of the actual peak locations compared with the initially estimated peak locations, while approximating the amplitudes to the expected values.
refinepeaks(wave,PL,freq,Method="NLS",LobeWidth=LW) yline(aTarget) % Theoretical peak amplitudes errorBounds = aTarget.*(1+0.03*[-1;1]); yline(errorBounds(:),":") % ±3% error bounds legend("Peak "+[1 2])
Input Arguments
y
— Input data
vector
Input data, specified as a vector. y
must be real and
must have at least three elements.
Data Types: double
| single
x
— Locations
vector | datetime
array
Locations, specified as a vector or a datetime
array. x
must
increase monotonically and have the same length as y
.
If x
is omitted, then the indices of y
are
used as locations.
Data Types: double
| single
| datetime
Fs
— Sample rate
positive scalar
Sample rate, specified as a positive scalar. The sample rate is the number of samples per unit time. If the unit of time is seconds, the sample rate has units of hertz.
Data Types: double
| single
Name-Value Arguments
Specify optional pairs of arguments as
Name1=Value1,...,NameN=ValueN
, where Name
is
the argument name and Value
is the corresponding value.
Name-value arguments must appear after other arguments, but the order of the
pairs does not matter.
Before R2021a, use commas to separate each name and value, and enclose
Name
in quotes.
Example: findpeaks(y,x,SortStr="descend",NPeaks=3)
finds the three tallest
peaks of the signal y
.
NPeaks
— Maximum number of peaks
positive integer scalar
Maximum number of peaks to return, specified as a positive integer scalar.
findpeaks
operates from the first element of the
input data and terminates when the number of peaks reaches the value of
'NPeaks'
.
Data Types: double
| single
SortStr
— Peak sorting
'none'
(default) | 'ascend'
| 'descend'
Peak sorting, specified as one of these values:
'none'
returns the peaks in the order in which they occur in the input data.'ascend'
returns the peaks in ascending or increasing order, from the smallest to the largest value.'descend'
returns the peaks in descending order, from the largest to the smallest value.
MinPeakHeight
— Minimum peak height
-Inf
(default) | real scalar
Minimum peak height, specified as a real scalar. Use this argument to have
findpeaks
return only those peaks higher than
'MinPeakHeight'
. Specifying a minimum peak height
can reduce processing time.
Data Types: double
| single
MinPeakProminence
— Minimum peak prominence
0 (default) | nonnegative real scalar
Minimum peak prominence, specified as a nonnegative real scalar. Use this argument to have
findpeaks
return only those peaks that have a
relative importance of at least 'MinPeakProminence'
.
For more information, see Prominence.
Data Types: double
| single
Threshold
— Minimum height difference
0 (default) | nonnegative real scalar
Minimum height difference between a peak and its neighbors, specified as a nonnegative real
scalar. Use this argument to have findpeaks
return
only those peaks that exceed their immediate neighboring values by at
least the value of 'Threshold'
.
Data Types: double
| single
MinPeakDistance
— Minimum peak separation
0 (default) | positive real scalar
Minimum peak separation, specified as a positive real scalar. When you specify a value for
'MinPeakDistance'
, the algorithm chooses the
tallest peak in the signal and ignores all peaks within
'MinPeakDistance'
of it. The function then
repeats the procedure for the tallest remaining peak and iterates until
it runs out of peaks to consider.
If you specify a location vector,
x
, then'MinPeakDistance'
must be expressed in terms ofx
. Ifx
is adatetime
array, then specify'MinPeakDistance'
as aduration
scalar or as a numeric scalar expressed in days.If you specify a sample rate,
Fs
, then'MinPeakDistance'
must be expressed in units of time.If you specify neither
x
norFs
, then'MinPeakDistance'
must be expressed in units of samples.
Use this argument to have findpeaks
ignore small peaks that occur in the neighborhood of a larger
peak.
Data Types: double
| single
| duration
WidthReference
— Reference height for width measurements
'halfprom'
(default) | 'halfheight'
Reference height for width measurements, specified as either 'halfprom'
or
'halfheight'
. findpeaks
estimates the width of a peak as the distance between the points where
the descending signal intercepts a horizontal reference line. The height
of the line is selected using the criterion specified in
'WidthReference'
:
'halfprom'
positions the reference line beneath the peak at a vertical distance equal to half the peak prominence. See Prominence for more information.'halfheight'
positions the reference line at one-half the peak height. The line is truncated if any of its intercept points lie beyond the borders of the peaks selected by setting'MinPeakHeight'
,'MinPeakProminence'
, and'Threshold'
. The border between peaks is defined by the horizontal position of the lowest valley between them. Peaks with height less than zero are discarded.
The locations of the intercept points are computed by linear interpolation.
MinPeakWidth
— Minimum peak width
0 (default) | positive real scalar
Minimum peak width, specified as a positive real scalar. Use this argument to select only
those peaks that have widths of at least
'MinPeakWidth'
.
If you specify a location vector,
x
, then'MinPeakWidth'
must be expressed in terms ofx
. Ifx
is adatetime
array, then specify'MinPeakWidth'
as aduration
scalar or as a numeric scalar expressed in days.If you specify a sample rate,
Fs
, then'MinPeakWidth'
must be expressed in units of time.If you specify neither
x
norFs
, then'MinPeakWidth'
must be expressed in units of samples.
Data Types: double
| single
| duration
MaxPeakWidth
— Maximum peak width
Inf
(default) | positive real scalar
Maximum peak width, specified as a positive real scalar. Use this argument to select only
those peaks that have widths of at most
'MaxPeakWidth'
.
If you specify a location vector,
x
, then'MaxPeakWidth'
must be expressed in terms ofx
. Ifx
is adatetime
array, then specify'MaxPeakWidth'
as aduration
scalar or as a numeric scalar expressed in days.If you specify a sample rate,
Fs
, then'MaxPeakWidth'
must be expressed in units of time.If you specify neither
x
norFs
, then'MaxPeakWidth'
must be expressed in units of samples.
Data Types: double
| single
| duration
Annotate
— Plot style
'peaks'
(default) | 'extents'
Plot style, specified as one of these values:
'peaks'
plots the signal and annotates the location and value of every peak.'extents'
plots the signal and annotates the location, value, width, and prominence of every peak.
This argument is ignored if you call findpeaks
with
output arguments.
Output Arguments
pks
— Local maxima
vector
Local maxima, returned as a vector of signal values. If there
are no local maxima, then pks
is empty.
locs
— Peak locations
vector
Peak locations, returned as a vector.
If you specify a location vector,
x
, thenlocs
contains the values ofx
at the peak indices.If you specify a sample rate,
Fs
, thenlocs
is a numeric vector of time instants with a time difference of 1/Fs
between consecutive samples.If you specify neither
x
norFs
, thenlocs
is a vector of integer indices.
w
— Peak widths
vector
Peak widths, returned as a vector of real numbers. The width
of each peak is computed as the distance between the points to the
left and right of the peak where the signal intercepts a reference
line whose height is specified by WidthReference
.
The points themselves are found by linear interpolation.
p
— Peak prominences
vector
Peak prominences, returned as a vector of real numbers. The prominence of a peak is the minimum vertical distance that the signal must descend on either side of the peak before either climbing back to a level higher than the peak or reaching an endpoint. See Prominence for more information.
More About
Prominence
The prominence of a peak measures how much the peak stands out due to its intrinsic height and its location relative to other peaks. A low isolated peak can be more prominent than one that is higher but is an otherwise unremarkable member of a tall range.
To measure the prominence of a peak:
Place a marker on the peak.
Extend a horizontal line from the peak to the left and right until the line does one of the following:
Crosses the signal because there is a higher peak
Reaches the left or right end of the signal
Find the minimum of the signal in each of the two intervals defined in Step 2. This point is either a valley or one of the signal endpoints.
The higher of the two interval minima specifies the reference level. The height of the peak above this level is its prominence.
findpeaks
makes no assumption about the behavior of the signal beyond its
endpoints, whatever their height. As a result, Steps 2 and 4 disregard signal
behavior beyond endpoints, which often affects the value of the reference level.
Consider for example the peaks of this signal:
Peak Number | Left Interval Lies Between Peak and | Right Interval Lies Between Peak and | Lowest Point on the Left Interval | Lowest Point on the Right Interval | Reference Level (Highest Minimum) |
---|---|---|---|---|---|
1 | Left end | Crossing due to peak 2 | Left endpoint | a | a |
2 | Left end | Right end | Left endpoint | h | Left endpoint |
3 | Crossing due to peak 2 | Crossing due to peak 4 | b | c | c |
4 | Crossing due to peak 2 | Crossing due to peak 6 | b | d | b |
5 | Crossing due to peak 4 | Crossing due to peak 6 | d | e | e |
6 | Crossing due to peak 2 | Right end | d | h | d |
7 | Crossing due to peak 6 | Crossing due to peak 8 | f | g | g |
8 | Crossing due to peak 6 | Right end | f | h | f |
9 | Crossing due to peak 8 | Crossing due to right endpoint | h | i | i |
Tips
You can initially estimate signal peaks with findpeaks
, and
then enhance their amplitudes and locations with refinepeaks
.
Assume you have a signal with amplitudes y
and locations
x
. The following code snippet shows how you can estimate and
refine peaks from y
and x
.
[yPeaks,xPeaksIdx] = findpeaks(y); [yRPeaks,xRPeaks] = refinepeaks(y,xPeaksIdx,x)
Extended Capabilities
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
Usage notes and limitations:
The
findpeaks
function does not supportdatetime
inputs for code generation.
GPU Code Generation
Generate CUDA® code for NVIDIA® GPUs using GPU Coder™.
Usage notes and limitations:
The
findpeaks
function does not supportdatetime
inputs for code generation.
GPU Arrays
Accelerate code by running on a graphics processing unit (GPU) using Parallel Computing Toolbox™.
This function fully supports GPU arrays. For more information, see Run MATLAB Functions on a GPU (Parallel Computing Toolbox).
Version History
Introduced in R2007bR2024b: findpeaks
supports GPU Code Generation
The findpeaks
function supports code generation for
graphical processing units (GPUs). You must have MATLAB®
Coder™ and GPU Coder™ to generate CUDA® code.
See Also
fminbnd
| fminsearch
| fzero
| islocalmax
| islocalmin
| max
| refinepeaks
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)