Finding peaks and troughs in a noisy curve

I needed to find the extremities of a noisy curve. This is a good example where you need to translate a qualitative observation to a quantitative one. It’s easy for a human to look at a curve and say where the important peaks and troughs are while ignoring those which are not important in the context of that curve. Here’s a simple algorithm that achieves it. To see it in action, just draw any curve and click the ‘find minmax’ button to see which points along your curve the algorithm decides to be the peaks (in green) or troughs (in red)

The algorithm is very naive and has a complexity of O(n) where n are the number of points on the curve (I use the term curve loosely as it doesn’t have to be continuous). It basically does the following:

Determine a threshold (defined arbitrarily as 10% of the difference between the lowest and highest points on the curve).

Get the Y coordinate of the leftmost point on the curve

Set horizontal boundaries as y+threshold and y-threshold

Scan the points of the curve from left to right and check the Y coordinate of the point

I’ll discuss what happens when the Y coordinate crosses the y+threshold that was set (the same principle applies if the Y coordinate gets below the y-threshold point).

We know that we have found a candidate for a maximum:

If there was a previous minimum point, mark it as such

Change the state to indicate we are now looking for a minimum point

Reset the thresholds boundaries to be the current Y coordinate plus and minus the threshold

Save the X,Y coordinates of the maximum candidate

Continue scanning and:

Update the X and Y coordinates of the maximum point candidate if the current Y coordinate is higher than the pervious maximum point candidate

Mark the maximum point candidate as a maximum when we cross the low threshold (this basically brings us back to step 1)