Find local maxima

returns
a vector with the local maxima (peaks) of the input signal vector, `pks`

= findpeaks(`data`

)`data`

.
A *local peak* is a data sample that is either
larger than its two neighboring samples or is equal to `Inf`

.
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 pair 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.

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 = 15 10 20

Use `findpeaks`

without output arguments to display the peaks.

findpeaks(data)

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 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))'))

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 proms

widths = 0.0154 0.0431 0.0377 0.0625 0.0274 0.0409 proms = 2.6816 5.5773 3.1448 4.4171 2.9191 3.6363

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

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)
```

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 . Specify a sample rate of 100 Hz and a sample time of one second. 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)

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)
```

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')

`data`

— Input datavectorInput data, specified as a vector. `data`

must
be real and must have at least three elements.

**Data Types: **`single`

| `double`

`x`

— Locationsvector | `datetime`

arrayLocations, specified as a vector or a `datetime`

array. `x`

must
increase monotonically and have the same length as `data`

.
If `x`

is omitted, then the indices of `data`

are
used as locations.

**Data Types: **`single`

| `double`

| `datetime`

`Fs`

— Sample ratepositive scalarSample 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: **`single`

| `double`

Specify optional comma-separated pairs of `Name,Value`

arguments.
`Name`

is the argument
name and `Value`

is the corresponding
value. `Name`

must appear
inside single quotes (`' '`

).
You can specify several name and value pair
arguments in any order as `Name1,Value1,...,NameN,ValueN`

.

`'SortStr','descend','NPeaks',3`

finds
the three tallest peaks of the signal.`'NPeaks'`

— Maximum number of peakspositive integer scalarMaximum number of peaks to return, specified as the comma-separated
pair consisting of `'NPeaks'`

and 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: **`single`

| `double`

`'SortStr'`

— Peak sorting`'none'`

(default) | `'ascend'`

| `'descend'`

Peak sorting, specified as the comma-separated pair consisting
of `'SortStr'`

and 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.

**Data Types: **`char`

`'MinPeakHeight'`

— Minimum peak height`-Inf`

(default) | real scalarMinimum peak height, specified as the comma-separated pair consisting
of `'MinPeakHeight'`

and 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: **`single`

| `double`

`'MinPeakProminence'`

— Minimum peak prominence0 (default) | real scalarMinimum peak prominence, specified as the comma-separated pair
consisting of `'MinPeakProminence'`

and a real scalar.
Use this argument to have `findpeaks`

return only
those peaks that have a relative importance of at least `'MinPeakProminence'`

.
See Prominence for more information.

**Data Types: **`single`

| `double`

`'Threshold'`

— Minimum height difference0 (default) | nonnegative real scalarMinimum height difference between a peak and its neighbors,
specified as the comma-separated pair consisting of `'Threshold'`

and
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: **`single`

| `double`

`'MinPeakDistance'`

— Minimum peak separation0 (default) | positive real scalarMinimum peak separation, specified as the comma-separated pair
consisting of `'MinPeakDistance'`

and 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 of`x`

. If`x`

is a`datetime`

array, then specify`'MinPeakDistance'`

as a`duration`

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`

nor`Fs`

, 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: **`single`

| `double`

| `duration`

`'WidthReference'`

— Reference height for width measurements`'halfprom'`

(default) | `'halfheight'`

Reference height for width measurements, specified as the comma-separated
pair consisting of `'WidthReference'`

and 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.

**Data Types: **`char`

`'MinPeakWidth'`

— Minimum peak width0 (default) | positive real scalarMinimum peak width, specified as the comma-separated pair consisting
of `'MinPeakWidth'`

and 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 of`x`

. If`x`

is a`datetime`

array, then specify`'MinPeakWidth'`

as a`duration`

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`

nor`Fs`

, then`'MinPeakWidth'`

must be expressed in units of samples.

**Data Types: **`single`

| `double`

| `duration`

`'MaxPeakWidth'`

— Maximum peak width`Inf`

(default) | positive real scalarMaximum peak width, specified as the comma-separated pair consisting
of `'MaxPeakWidth'`

and 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 of`x`

. If`x`

is a`datetime`

array, then specify`'MaxPeakWidth'`

as a`duration`

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`

nor`Fs`

, then`'MaxPeakWidth'`

must be expressed in units of samples.

**Data Types: **`single`

| `double`

| `duration`

`'Annotate'`

— Plot style`'peaks'`

(default) | `'extents'`

Plot style, specified as the comma-separated pair consisting
of `'Annotate'`

and 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.

**Data Types: **`char`

`pks`

— Local maximavectorLocal maxima, returned as a vector of signal values. If there
are no local maxima, then `pks`

is empty.

**Data Types: **`single`

| `double`

`locs`

— Peak locationsvectorPeak locations, returned as a vector.

If you specify a location vector,

`x`

, then`locs`

contains the values of`x`

at the peak indices.If you specify a sample rate,

`Fs`

, then`locs`

is a vector of time instants.If you specify neither

`x`

nor`Fs`

, then`locs`

is a vector of integer indices.

**Data Types: **`single`

| `double`

`w`

— Peak widthsvectorPeak 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.

If you specify a location vector,

`x`

, then the widths are expressed in terms of`x`

.If you specify a sample rate,

`Fs`

, then the widths are expressed in units of time.If you specify neither

`x`

nor`Fs`

, then the widths are expressed in units of samples.

**Data Types: **`single`

| `double`

`p`

— Peak prominencesvectorPeak 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.

**Data Types: **`single`

| `double`

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. This is
reflected in Steps 2 and 4 and 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` |

`fminbnd`

| `fminsearch`

| `fzero`

| `max`

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.

Was this topic helpful?

You can also select a location from the following list:

- Canada (English)
- United States (English)

- 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)