I am trying to identify the R peak of an ECG. I have used the following line of code to do this:
peaks=signal.find_peaks_cwt(signal_slice, widths=np.arange(1,80))
fig, ax = plt.subplots()
ax.set_title('Detect R peak')
ax.plot(signal_slice)
for peak in peaks:
ax.axvline(x=peak, color='r')
And I get the following output:
However, with the following signal it inaccurately detects the smaller peak also.
Now it has stopped wrongly detecting the small peaks, but still seems to randomly miss the large peak, does anyone know why?
You should specify the widths to the expected width of the peak. From the Scipy documentation:
1-D array of widths to use for calculating the CWT matrix. In general, this range should cover the expected width of peaks of interest.
Here is an example to illustrate the effect of width.
from scipy import signal
xs = np.arange(0, 20*np.pi, 0.05)
xs2 = np.arange(0, 20*np.pi, 0.025)
data = np.sin(xs)
data2 = np.sin(xs2)
data= data + data2[:1257]
peakind = signal.find_peaks_cwt(data, np.arange(1,200))
peakind, xs[peakind], data[peakind]
fig, ax = plt.subplots()
ax.set_title('Detect R peak')
ax.plot(data)
for peak in peakind:
ax.axvline(x=peak, color='r')
This results in only the global peaks.
But if you change the width to np.arange(1,100), you will also see the other local peak.
peakind = signal.find_peaks_cwt(data, np.arange(1,100))
Here the methods detects more peaks due to the difference in width.