Mahsolid
Mahsolid

Reputation: 433

Detecting peaks in python plots

My data file is shared in the following link.

We can plot this data using the following script.

import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook

def read_datafile(file_name):

    data = np.loadtxt(file_name, delimiter=',')
    return data

data = read_datafile('mah_data.csv')


fig = plt.figure()

ax1 = fig.add_subplot(111)

ax1.set_title("Data")    
ax1.set_xlabel('t')
ax1.set_ylabel('s')

ax1.plot(x,y, c='r', label='My data')

leg = ax1.legend()

plt.show()

How can we detect peaks in python? I can't find a suitable peak detection algorithm in Python.

Upvotes: 4

Views: 13076

Answers (3)

Arun
Arun

Reputation: 295

You can use the argrelextrema function in scipy.signal to return the indices of the local maxima or local minima of an array. This works for multi-dimensional arrays as well by specifying the axis.

from scipy.signal import argrelextrema

ind_max = argrelextrema(z, np.greater) # indices of the local maxima
ind_min = argrelextrema(z, np.less)  # indices of the local minima

maxvals = z[ind_max]
minvals = z[ind_min]

More specifically, one can use the argrelmax or argrelmin to find the local maximas or local minimas. This also works for multi dimensional arrays using the axis argument.

from scipy.signal import argrelmax, argrelmin

ind_max = argrelmax(z, np.greater) # indices of the local maxima
ind_min = argrelmin(z, np.less)  # indices of the local minima

maxvals = z[ind_max]
minvals = z[ind_min]

For more details, one can refer to this link: https://docs.scipy.org/doc/scipy/reference/signal.html#peak-finding

Upvotes: 4

erdogant
erdogant

Reputation: 1694

Try the findpeaks library.

pip install findpeaks

I can not find the data attached but suppose the data is a vector and stored in data:

import pandas as pd
data = pd.read_csv("mah_data.csv", header=None).values

# Import library
from findpeaks import findpeaks

# If the resolution of your data is low, I would recommend the ``lookahead`` parameter, and if your data is "bumpy", also the ``smooth`` parameter.
fp = findpeaks(lookahead=1, interpolate=10)
# Find peaks
results = fp.fit(data)
# Make plot
fp.plot()

# Results with respect to original input data.
results['df']

# Results based on interpolated smoothed data.
results['df_interp']

Upvotes: 1

zenravs
zenravs

Reputation: 41

Try using peakutil (http://pythonhosted.org/PeakUtils/). Here is my solution to your question using peakutil.

import pandas as pd
import peakutils
data = pd.read_csv("mah_data.csv", header=None)
ts = data[0:10000][1] # Get the second column in the csv file
print(ts[0:10]) # Print the first 10 rows, for quick testing
# check peakutils for all the parameters.
# indices are the index of the points where peaks appear
indices = peakutils.indexes(ts, thres=0.4, min_dist=1000)
print(indices) 

You should also checkout peak finding in scipy (https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks_cwt.html)

Upvotes: 3

Related Questions