7

I am trying to understand the FindPeaks function in V10. I have two questions. Here is some measured data with noise.

data = {{182.6`, 0.08622910543312512`}, {182.7`, 
0.08537299262452944`}, {182.79999999999998`, 
0.08509477035006817`}, {182.9`, 0.0845805258347419`}, {183.`, 
0.0833228764826812`}, {183.1`, 0.0839126306989993`}, {183.2`, 
0.08291375251342525`}, {183.3`, 0.08240823659876313`}, {183.4`, 
0.0830234147404793`}, {183.5`, 0.08134478053584769`}, {183.6`, 
0.08079856133452573`}, {183.7`, 0.08050559743186467`}, {183.8`, 
0.08080142572471936`}, {183.89999999999998`, 
0.07955082017792586`}, {184.`, 0.07920192550765708`}, {184.1`, 
0.07913077277220741`}, {184.2`, 
0.07851045343456126`}, {184.29999999999998`, 
0.07827811148297717`}, {184.4`, 0.07790658439240977`}, {184.5`, 
0.07872378008473063`}, {184.6`, 0.0778929016975709`}, {184.7`, 
0.07712497543207282`}, {184.8`, 0.0773142043365139`}, {184.9`, 
0.07677112179678972`}, {185.`, 0.07714917185712153`}, {185.1`, 
0.07609793883257307`}, {185.2`, 0.07647292614875555`}, {185.3`, 
0.07586422613054548`}, {185.39999999999998`, 
0.07503402555148043`}, {185.5`, 0.07535492258842982`}, {185.6`, 
0.07479720387520067`}, {185.7`, 
0.07502168284480967`}, {185.79999999999998`, 
0.07475705268743123`}, {185.9`, 0.07411938622704159`}, {186.`, 
0.07500732335655166`}, {186.1`, 0.07421809974702932`}, {186.2`, 
0.07342212354062684`}, {186.3`, 0.07365489544764585`}, {186.4`, 
0.07336815610833888`}, {186.5`, 0.07363242236825435`}, {186.6`, 
0.07315192972926646`}, {186.7`, 0.07330679697249187`}, {186.8`, 
0.0733269167127279`}, {186.89999999999998`, 
0.0731251716924564`}, {187.`, 0.07260278352658113`}, {187.1`, 
0.07306968191644458`}, {187.2`, 
0.07290770361093614`}, {187.29999999999998`, 
0.07283251650826833`}, {187.4`, 0.07283442908533787`}, {187.5`, 
0.0727933891934353`}, {187.6`, 0.07249592335566046`}, {187.7`, 
0.07197844832015894`}, {187.8`, 0.07263493512946399`}, {187.9`, 
0.07174948968346886`}, {188.`, 0.07253555403668858`}, {188.1`, 
0.07245508553439435`}, {188.2`, 0.07184010069755509`}, {188.3`, 
0.07221620673218568`}, {188.39999999999998`, 
0.07187284663607331`}, {188.5`, 0.07178327326124803`}, {188.6`, 
0.07208965301507222`}, {188.7`, 
0.07250651648005164`}, {188.79999999999998`, 
0.07257446566043749`}, {188.9`, 0.07227287184818783`}, {189.`, 
0.07223352419166103`}, {189.1`, 0.07243472666747373`}, {189.2`, 
0.07171820927086656`}, {189.3`, 0.07204001488569149`}, {189.4`, 
0.0723265757849197`}, {189.5`, 0.07261568975528293`}, {189.6`, 
0.0730258896097459`}, {189.7`, 0.07290819207399675`}, {189.8`, 
0.07237119231231051`}, {189.89999999999998`, 
0.07288067946929049`}, {190.`, 0.07315636826782`}, {190.1`, 
0.07323064842780881`}, {190.2`, 
0.07313593217571408`}, {190.29999999999998`, 
0.07272950603750794`}, {190.4`, 0.07274990550949453`}, {190.5`, 
0.07450677007995525`}, {190.6`, 0.07365573970201258`}, {190.7`, 
0.07433883840990217`}, {190.8`, 0.07446104858175041`}, {190.9`, 
0.0737982277263017`}, {191.`, 0.07506685384392282`}, {191.1`, 
0.07395376211266148`}, {191.2`, 0.0742092287720052`}, {191.3`, 
0.07433236843377936`}, {191.39999999999998`, 
0.0743286784215887`}, {191.5`, 0.07509393533091145`}, {191.6`, 
0.07504044097854737`}, {191.7`, 
0.07542023815079207`}, {191.79999999999998`, 
0.07533117894349618`}, {191.9`, 0.07552783101700196`}, {192.`, 
0.0754022915717515`}, {192.1`, 0.07506670583667117`}, {192.2`, 
0.07514646811885288`}, {192.29999999999998`, 
0.0751437726939356`}, {192.39999999999998`, 
0.07510984668763601`}, {192.5`, 
0.07575225459754319`}, {192.60000000000002`, 
0.07524450698869306`}, {192.7`, 0.07517418238665477`}, {192.8`, 
0.07529888198343905`}, {192.89999999999998`, 
0.07570648686665757`}, {193.`, 
0.07471855104307323`}, {193.09999999999997`, 
0.07470370962176116`}, {193.20000000000002`, 
0.0740939074784806`}, {193.3`, 0.07351240317384786`}, {193.4`, 
0.07252279668073432`}, {193.5`, 0.07244617796064005`}, {193.6`, 
0.07223255780156779`}, {193.7`, 
0.07091971082002622`}, {193.79999999999998`, 
0.07077788861127683`}, {193.89999999999998`, 
0.06894575502867846`}, {194.`, 
0.06835408075614947`}, {194.10000000000002`, 
0.06655432733896739`}, {194.2`, 0.06570882741630242`}, {194.3`, 
0.06418059038217878`}, {194.39999999999998`, 
0.06155801742094924`}, {194.5`, 
0.06011166542028025`}, {194.59999999999997`, 
0.057660421984647894`}, {194.70000000000002`, 
0.05613992661747851`}, {194.8`, 0.05409075908076599`}, {194.9`, 
0.051315636687986436`}, {195.`, 0.04900808466296439`}, {195.1`, 
0.04737450255887146`}, {195.2`, 
0.044717642692112675`}, {195.29999999999998`, 
0.04215076442442378`}, {195.39999999999998`, 
0.04043501571848719`}, {195.5`, 
0.038336212965640624`}, {195.60000000000002`, 
0.03698884260624359`}, {195.7`, 0.03547188291350474`}, {195.8`, 
0.03427111635640652`}, {195.89999999999998`, 
0.03292367507634511`}, {196.`, 
0.031725998559319055`}, {196.09999999999997`, 
0.030617531350743906`}, {196.20000000000002`, 
0.030130328209670976`}, {196.3`, 0.02904116807320502`}, {196.4`, 
0.029909038090697886`}, {196.5`, 0.02843229368886636`}, {196.6`, 
0.02901355337761649`}, {196.7`, 
0.028979862157444008`}, {196.79999999999998`, 
0.02878295276966388`}, {196.89999999999998`, 
0.028957775820142927`}, {197.`, 
0.028478060827705626`}, {197.10000000000002`, 
0.028938071812635816`}, {197.2`, 0.029117185893924716`}, {197.3`, 
0.02938853974695918`}, {197.39999999999998`, 
0.030229940909354804`}, {197.5`, 
0.029485217109400212`}, {197.59999999999997`, 
0.03079402559401292`}, {197.70000000000002`, 
0.03051245715482414`}, {197.8`, 0.03056375822253502`}, {197.9`, 
0.030788085920261856`}, {198.`, 0.030910098047144976`}, {198.1`, 
0.031440349336531115`}, {198.2`, 
0.03143726784808395`}, {198.29999999999998`, 
0.03239344050324954`}, {198.39999999999998`, 
0.03241545932012303`}, {198.5`, 
0.03198963279570552`}, {198.60000000000002`, 
0.03273789660624955`}, {198.7`, 0.032659053442336675`}, {198.8`, 
0.032791614417334115`}, {198.89999999999998`, 
0.032825069131018285`}, {199.`, 
0.03351436361528482`}, {199.09999999999997`, 
0.03322588178379325`}, {199.20000000000002`, 
0.03330962186643736`}, {199.3`, 0.034424827105306206`}, {199.4`, 
0.033860828677810505`}, {199.5`, 0.03412108912323206`}, {199.6`, 
0.03442038112319988`}, {199.7`, 
0.03464519084982945`}, {199.79999999999998`, 
0.034340806078424296`}, {199.89999999999998`, 
0.03513374907705739`}, {200.`, 
0.03502824611619059`}, {200.10000000000002`, 
0.03491243961946173`}, {200.2`, 0.03464927000318122`}, {200.3`, 
0.035526135011944446`}, {200.39999999999998`, 
0.03476230230393778`}, {200.5`, 
0.03564752384075454`}, {200.59999999999997`, 
0.03557719820846709`}, {200.70000000000002`, 
0.035955794122767386`}, {200.8`, 0.03571660745453507`}, {200.9`, 
0.035964735338650945`}, {201.`, 0.03617643844690327`}, {201.1`, 
0.03564424939619923`}, {201.2`, 
0.036812938339660095`}, {201.29999999999998`, 
0.036710308908121075`}};

If I drop the x values I can get FindPeaks to work well

ListPlot[{data[[All, 2]], FindPeaks[data[[All, 2]], 5]}]

Mathematica graphics

This does a good job of finding the local maximum at about 100. Question: how does the second parameter work? Is the scale of the Gaussian blurr just the number of points? I loose my maximum if I set the scale to 19 and have too many peaks if it is 2.

Second question. How do I get my x axis values back? Below is a terrible hack. Is there a better method?

a =.; b =.;
a = FindPeaks[data[[All, 2]], 5];
b = Transpose[{data[[All, 1]][[a[[All, 1]]]], a[[All, 2]]}];
ListPlot[{data, b}]

Mathematica graphics

A good reference not using FindPeaks can be found here.

Thanks

Hugh
  • 16,387
  • 3
  • 31
  • 83

2 Answers2

3

Regarding your second question:

Second question. How do I get my x axis values back? Below is a terrible hack. Is there a better method?

I think it is best to use TimeSeries:

ts = TimeSeries[data];
ListPlot[{ts, FindPeaks[ts, 0.1]}]

In order to select a parameter for FindPeaks it might be better to use these plot commands:

ts = TimeSeries[data];
Show[{ListLinePlot[ts, PlotStyle -> Gray], 
  ListPlot[FindPeaks[ts, 2], PlotStyle -> {Red, PointSize -> 0.004}]}, ImageSize -> 800]

enter image description here

Anton Antonov
  • 37,787
  • 3
  • 100
  • 178
  • Thanks for pointing out TimeSeries. This is an old question and I think it predates TimeSeries. It looks like it could be useful I must find out more about it. – Hugh Sep 25 '15 at 21:20
  • @Hugh Sure! I also have a solution of not using FindPeaks. Are you interested in using FindPeaks or not? Do you have some criteria with which you are/were able to judge which set of peaks is good or not? – Anton Antonov Sep 25 '15 at 21:34
  • The trouble with this data is that I want just one peak and too much smoothing looses the peak all together. This is just one interval in a long time series and I can't afford to tune each peak individually. – Hugh Sep 25 '15 at 21:41
  • @Hugh I applied Quantile Regression to this problem and since you posted this link: https://mathematica.stackexchange.com/questions/23828/finding-local-minima-maxima-in-noisy-data , I went ahead and implemented a solution for that problem and posted an answer. Would that or similar solution be of interested to you? – Anton Antonov Sep 27 '15 at 19:53
2

In a comment, Bob Hanlon offers a simpler solution to your second problem (getting the x-axis values back), namely:

b = data[[First /@ a]]

Although you could of course convert to a TimeSeries[] and work on that rather than the 1D data.

Now, with regards to the first question, you can investigate the behaviour of the scale parameter by Gaussian-filtering the data yourself, which is all FindPeaks[] is doing:

ListLinePlot[
    Transpose[{data[[All, 1]], GaussianFilter[data[[All, 2]], {2*#, #}]}] & /@ {5, 20, 50}]

You can see how the maxima disappears as the scale parameter increases, and see which peaks survive the Gaussian blur as described in the documentation. You can also specify a third "sharpness" parameter if necessary.

enter image description here

dr.blochwave
  • 8,768
  • 3
  • 42
  • 76
  • 1
    Thank you. This is an old post but one I am still trying to understand. I now see that there is a special Gaussian kernel which FindPeaks uses. I had previously been thinking that I had to do the filtering myself prior to using FindPeaks – Hugh Sep 25 '15 at 21:30
  • @Hugh glad I can help - if you look in the documentation for FindPeaks you'll see it uses an example similar to mine abou the GaussianFilter step. – dr.blochwave Sep 25 '15 at 21:40
  • I suspect I want the reverse of sharpness. I only want one peak in the interval. Too much smoothing and there is no peak too little and there are several. Furthermore this is just one part of a much longer time history which I can't look at manually. – Hugh Sep 25 '15 at 21:54
  • @Hugh does the 4th option of all peaks above a threshold help at all? FindPeaks[data,σ,s,t] finds only peaks with values greater than t, and you can also set independent scales for sharpness and threshold. – dr.blochwave Sep 25 '15 at 21:57
  • I have a huge range in my data with peaks in valleys and small valleys between some peaks and rising and falling trends so a threshold is not going to work. I am looking at vibration spectra. – Hugh Sep 25 '15 at 22:02
  • @Hugh is this question of any use? http://mathematica.stackexchange.com/questions/5575/how-to-find-all-the-local-minima-maxima-in-a-range – dr.blochwave Sep 25 '15 at 22:04
  • No, I have noise so I need some smoothing. That's a nice post though. – Hugh Sep 25 '15 at 22:06
  • @Hugh I guess you could smooth before using the answers in the link. But automatically determining parameters given huge variations in the data range may well be beyond FindPeaks[]! – dr.blochwave Sep 25 '15 at 22:08