I am writing code to find the local minima and maxima of the gradient of a signal similar to this stackoverflow question. I am using argrelextrema to do this. To test my my approach I implemented a quick test using the Cosine function.
# Get the data
x = np.arange(start=0,
stop=20,
step=0.2)
y = np.cos(x)
# Calculate the gradient
gradient = []
for y1, y2 in zip(y, y[1:]):
# Append the gradient (Delta Y / Delta X) where Delta X = 1
gradient.append(y2-y1)
# Turn the gradient from a list to an array
gradient = np.array(gradient)
# Calculate the maximum points of the gradient
maxima = argrelextrema(gradient, np.greater_equal, order=2)
minima = argrelextrema(gradient, np.less_equal, order=2)
# Plot the original signal
plt.plot(x, y, label="Original Signal")
plt.scatter(x[maxima], y[maxima], color="red", label="Maxima")
plt.scatter(x[minima], y[minima], color="blue", label="Minima")
plt.title("Original Graph")
plt.legend(loc='lower left')
plt.show()
# Plot the gradient
plt.plot(gradient, label="First Derivative")
plt.scatter(maxima, gradient[maxima], color="red", label="Maxima")
plt.scatter(minima, gradient[minima], color="blue", label="Minima")
plt.title("1st Derivative Graph")
plt.legend(loc='lower left')
plt.show()
This gives the following results:
All seems well. However when I change the code such that:
x = [my data of 720 points]
y = [my data of 720 points some are np.inf]
Link to the data (saved as a '.txt' file)
I get really strange results as seen below:
At first, I thought it could be due to the order=2
parameter of the argrelextrema
function or noise in my signal. Changing the order
to a larger window size reduces the number of points found, and so does including a digital filter. I, however, still can't understand why does it not find the maxima and minima at the peaks of the gradient rather than simply along the flat region?
Note: This question had the inverse of my problem.
Edit:
Changing the parameters less_equal
to less
and greater_equal
to greater
also removes many of the points along the flat region. Although I am still confused why the maxima and minima of the gradient are not selected.