I just translated to Python from this MATLAB script, which I've also included here.
Also see Frequency estimation methods in Python for interpolating to get sharp intersample peaks
sixtenbe has posted a more powerful version here
I just translated to Python from this MATLAB script, which I've also included here.
Also see Frequency estimation methods in Python for interpolating to get sharp intersample peaks
sixtenbe has posted a more powerful version here
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() |