# How to find local minima of data using PeakDetect

One of the great new function in v10 is PeakDetect.

It can detect peaks (local maxima) according to desired sharpness as shown in this example:

data = Table[{x, (Sin[10 x] + 2) Exp[-x^2]}, {x, -4, 4, .01}];
peaks = Pick[data, PeakDetect[data[[;; , 2]], .01, .0005], 1];
ListPlot[{data, peaks},
PlotStyle -> {Automatic, Directive[Red, PointSize[0.02]]}] The question is how to find valleys (local minima) of the such data using this new function?

• Apply it to $-f$? Jul 14, 2014 at 1:04
• @MarkMcClure Just saw your comment after I posted it. Yes, that is the first thing I though about also. Jul 14, 2014 at 1:08
• @MarkMcClure great trick. thanks to you and to Nasser. Jul 14, 2014 at 1:09

As has been observed data = Table[{x, (Sin[10 x] + 2) Exp[-x^2]}, {x, -4, 4, .01}];
peaks = Pick[data, PeakDetect[data[[;; , 2]], .01, .0005], 1];
troughs = Pick[data, PeakDetect[-data[[;; , 2]], .01, .0005], 1];
ListPlot[{data, peaks, troughs},
PlotStyle -> {Automatic, Directive[Red, PointSize[0.02]],
Directive[Green, PointSize[0.02]]}]

• It would be nice to have a method to find local minima and maxima in one go. For large data, this doubles the time, somewhat unnecessarily. Apr 27, 2016 at 11:38
• @IstvánZachar yes you are right. I will think about . It approaches 2 years since the answer. MMa has changed, I have changed but not in a desirable direction. I would very much value a better answer than mine. If you post one "comment me" in. Apr 27, 2016 at 11:41

Not an answer, more of a extended comment. (Since the question requires the use of PeakDetect.)

Some (more than half actually) of the local extrema are missed. This becomes obvious using Log plots (modifying the code of ubpdqn):

data = Table[{x, (Sin[10 x] + 2) Exp[-x^2]}, {x, -4, 4, .01}];
peaks = Pick[data, PeakDetect[data[[;; , 2]], .01, .0005], 1];
troughs = Pick[data, PeakDetect[-data[[;; , 2]], .01, .0005], 1];
opts = {PlotStyle -> {Automatic, Directive[Red, PointSize[0.02]],
Directive[Green, PointSize[0.02]]}, PlotTheme -> "Detailed",
ImageSize -> Medium};
Grid[{{ListPlot[{data, peaks, troughs}, opts],
ListLogPlot[{data, peaks, troughs}, opts]}}] I tried few times to get better results by tweaking the PeakDetect parameters without success.

Using Quantile regression fitting to find the local extrema gives better results:

Import["https://raw.githubusercontent.com/antononcube/MathematicaForPrediction/master/Applications/QuantileRegressionForLocalExtrema.m"]

Block[{data = data, qfuncs, showFunc},
{qfuncs, extrema} = QRFindExtrema[data, 40, 2, 12, {0.5}];
showFunc[listPlotFunc_] :=
listPlotFunc[Join[{data}, extrema],
PlotStyle -> {{}, {PointSize[Medium], Green}, {PointSize[Medium],
Red}}, PlotTheme -> "Detailed", PlotRange -> All,
ImageSize -> Medium];
Grid[{{showFunc[ListPlot], showFunc[ListLogPlot]}}]
] Here is a related discussion: "Finding very weak peaks".

data = Table[{x, -(Sin[10 x] + 2) Exp[-x^2]}, {x, -4, 4, .01}];
peaks = Pick[data, PeakDetect[data[[;; , 2]], .01, .0005], 1];
ListPlot[{data, peaks}, PlotStyle -> {Automatic, Directive[Red, PointSize[0.02]]}];
Rotate[%, 180 Degree] Or as Pickett mentioned below, just add - to data as in

data = Table[{x, (Sin[10 x] + 2) Exp[-x^2]}, {x, -4, 4, .01}];
peaks = Pick[data, PeakDetect[-data[[;; , 2]], .01, .0005], 1];
ListPlot[{data, peaks}, PlotStyle -> {Automatic, Directive[Red, PointSize[0.02]]}]

• It's easier to just add - in front of data[[;;,2]]. This way you don't have to rotate the graph. Jul 14, 2014 at 1:12
• @Nasser, it would better if you ListPlot[{-data,-peaks},....] Jul 14, 2014 at 1:13
• @Pickett, sure that is better so no rotation is needed. Thanks. Jul 14, 2014 at 1:13