Skip to content

Instantly share code, notes, and snippets.

@endolith
Last active July 27, 2024 19:48
Show Gist options
  • Save endolith/250860 to your computer and use it in GitHub Desktop.
Save endolith/250860 to your computer and use it in GitHub Desktop.
Peak detection in Python [Eli Billauer]
function [maxtab, mintab]=peakdet(v, delta, x)
%PEAKDET Detect peaks in a vector
% [MAXTAB, MINTAB] = PEAKDET(V, DELTA) finds the local
% maxima and minima ("peaks") in the vector V.
% MAXTAB and MINTAB consists of two columns. Column 1
% contains indices in V, and column 2 the found values.
%
% With [MAXTAB, MINTAB] = PEAKDET(V, DELTA, X) the indices
% in MAXTAB and MINTAB are replaced with the corresponding
% X-values.
%
% A point is considered a maximum peak if it has the maximal
% value, and was preceded (to the left) by a value lower by
% DELTA.
% Eli Billauer, 3.4.05 (Explicitly not copyrighted).
% This function is released to the public domain; Any use is allowed.
maxtab = [];
mintab = [];
v = v(:); % Just in case this wasn't a proper vector
if nargin < 3
x = (1:length(v))';
else
x = x(:);
if length(v)~= length(x)
error('Input vectors v and x must have same length');
end
end
if (length(delta(:)))>1
error('Input argument DELTA must be a scalar');
end
if delta <= 0
error('Input argument DELTA must be positive');
end
mn = Inf; mx = -Inf;
mnpos = NaN; mxpos = NaN;
lookformax = 1;
for i=1:length(v)
this = v(i);
if this > mx, mx = this; mxpos = x(i); end
if this < mn, mn = this; mnpos = x(i); end
if lookformax
if this < mx-delta
maxtab = [maxtab ; mxpos mx];
mn = this; mnpos = x(i);
lookformax = 0;
end
else
if this > mn+delta
mintab = [mintab ; mnpos mn];
mx = this; mxpos = x(i);
lookformax = 1;
end
end
end
import sys
from numpy import NaN, Inf, arange, isscalar, asarray, array
def peakdet(v, delta, x = None):
"""
Converted from MATLAB script at http://billauer.co.il/peakdet.html
Returns two arrays
function [maxtab, mintab]=peakdet(v, delta, x)
%PEAKDET Detect peaks in a vector
% [MAXTAB, MINTAB] = PEAKDET(V, DELTA) finds the local
% maxima and minima ("peaks") in the vector V.
% MAXTAB and MINTAB consists of two columns. Column 1
% contains indices in V, and column 2 the found values.
%
% With [MAXTAB, MINTAB] = PEAKDET(V, DELTA, X) the indices
% in MAXTAB and MINTAB are replaced with the corresponding
% X-values.
%
% A point is considered a maximum peak if it has the maximal
% value, and was preceded (to the left) by a value lower by
% DELTA.
% Eli Billauer, 3.4.05 (Explicitly not copyrighted).
% This function is released to the public domain; Any use is allowed.
"""
maxtab = []
mintab = []
if x is None:
x = arange(len(v))
v = asarray(v)
if len(v) != len(x):
sys.exit('Input vectors v and x must have same length')
if not isscalar(delta):
sys.exit('Input argument delta must be a scalar')
if delta <= 0:
sys.exit('Input argument delta must be positive')
mn, mx = Inf, -Inf
mnpos, mxpos = NaN, NaN
lookformax = True
for i in arange(len(v)):
this = v[i]
if this > mx:
mx = this
mxpos = x[i]
if this < mn:
mn = this
mnpos = x[i]
if lookformax:
if this < mx-delta:
maxtab.append((mxpos, mx))
mn = this
mnpos = x[i]
lookformax = False
else:
if this > mn+delta:
mintab.append((mnpos, mn))
mx = this
mxpos = x[i]
lookformax = True
return array(maxtab), array(mintab)
if __name__=="__main__":
from matplotlib.pyplot import plot, scatter, show
series = [0,0,0,2,0,0,0,-2,0,0,0,2,0,0,0,-2,0]
maxtab, mintab = peakdet(series,.3)
plot(series)
scatter(array(maxtab)[:,0], array(maxtab)[:,1], color='blue')
scatter(array(mintab)[:,0], array(mintab)[:,1], color='red')
show()
@v3nz3n
Copy link

v3nz3n commented Oct 25, 2013

thanks for the script.

to make it work I had to add asarray and pylab imports:

from numpy import NaN, Inf, arange, isscalar, array, asarray
from pylab import *

as well as actually show the matplotlib graph by adding (in the main function):

plot(series)
show()

@Zeokat
Copy link

Zeokat commented Mar 5, 2014

This piece of code saved Zeokat lots of hours. Thanks.

@endolith
Copy link
Author

@v3nz3n sorry, I'm not good at listing imports because I just did from pylab import *, but I'm trying to be better now. Spyder has pyflakes built in, which helps.

@Alymantara
Copy link

Works perfectly. Thanks for sharing!!!

@San08
Copy link

San08 commented Sep 2, 2014

I have a negative signal with a peak pointing downwards. When I use this code maxtab gives me the start of the peak and mintab gives me the maximum position of the peak.
I would like to get the start and end of the peak. Is there a way to find?

@iuribeferrari
Copy link

Thanks for sharing! A great help.

@martin-samouiller
Copy link

Thanks you !

@bancek
Copy link

bancek commented Oct 11, 2015

Thank you.

@nmningmei
Copy link

Thank you! Great help for search target waves in EEG data.

@Ruthygg
Copy link

Ruthygg commented Mar 22, 2016

Thanks a lot for this, do you have this in R?

@golobor
Copy link

golobor commented Jul 1, 2016

thanks for the code!

@algerianmaster
Copy link

please how to use this with PyOpenCl ?

@mpiannucci
Copy link

Here is a go version I converted https://github.com/mpiannucci/peakdetect

@Rishie13
Copy link

Rishie13 commented Dec 3, 2016

Is there a way I can preprocess csv files and show output for accelerometer?

@atikalidyad
Copy link

can i implement it in GNURadio? Thank you very much

@JorgeHormaza
Copy link

Mate, I just want to say Thank you so much because you save my life with this script.

@PZiso
Copy link

PZiso commented Mar 29, 2018

Great coding ! Thanks a lot!

@LuisAli22
Copy link

Thank you so much

@15738897318
Copy link

有关峰值点检测的研究促进这一领域的快速发展,我希望有志之士团结合作共同推进,同时我正在做峰值检测的学术课题,希望与有意者交流探讨,联系方式:[email protected],谢谢

@pelissarisergioo
Copy link

Thank you for this snippet, it works perfectly in my implementation.

@cgi1
Copy link

cgi1 commented Feb 4, 2020

Thanks man!

@TravisH0301
Copy link

Thanks for sharing your code! It works very well for my project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment