4

I have a list of data (two columns) and I want to plot in gnuplot only the value for which my second column has a local maximum.

To do so I would like to see if the second column of the ith row is bigger than the (i-1) and (i+1)th rows.

2 Answers 2

6

It can be done and I was bored enough to do it. I generated the following set of random data:

5191
29375
23222
32118
3185
32355
17173
8734
28850
20811
5956
6950
28560
25770
4630
28272
10035
7209
19428
26187
30784
20326
12865
23288
20924

Plotting the values against their position in the list looks like this:

enter image description here

You can spot the local maxima right away from the graph above. Now I can process the data points storing the two previous values (both x and y coordinates) in temporary variables, when I identify a maximum, I plot the data point:

# Select the columns of your data file that contain x and y data
# (usually 1 and 2 respectively)
xcolumn=0
ycolumn=1

plot "data" u (column(xcolumn)):(column(ycolumn)) w l, \
"data" u (column(0)==0 ? (last2y=column(ycolumn), \
last2x=column(xcolumn), 1/0) : column(0)==1 ? (lasty=column(ycolumn), \
lastx=column(xcolumn), 1/0) : lastx) \
: \
( column(0) < 2 ? 1/0 : (last2y < lasty && \
column(ycolumn) < lasty) ? (value=lasty, last2y=lasty, last2x=lastx, \
lasty=column(ycolumn), lastx=column(xcolumn), value) : (last2y=lasty, \
last2x=lastx, lasty=column(ycolumn), lastx=column(xcolumn), 1/0)) pt 7

enter image description here

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you very much that seems perfect. However, did you have only one column in your file? I have two in my case and I think I need to adapt the code. but I am not sure to understand exactly the meaning of column(0)
I managed to make it work, but now I would like to make lines instead of points, is it possible?
See the edited answer for a general solution. For lines you'll need to plot to a table (only the points, skip the first plot "data"), then filter it to remove the invalid points: set table "table"; plot ...; unset table; plot "< grep "i" table" w l.
I already wrote that but it does not work. If I put linepoints lp only the points appear.
@Miguel, thank you very much it works. Is it possible to print the count of the peaks?
|
6

A simple gnuplot peak finder

Comparing 3 consecutive data points is a simple way to look for maxima/peaks.

if y(i-1) < y(i) > y(i+1) then you have a maximum/peak at x(i).

However, if you have noisy curves (like experimental spectra typically are) you will get too many "peaks".

The script below basically calculates for each peak a specific number which is a measure for the "independence" of a peak (see Topographic prominence). Note that a high peak intensity does not automatically mean high prominence. The script requires gnuplot>=5.4.0 since it uses:

  • datablocks
  • plot ... with table
  • smooth zsort (available since 5.4.0)

The prominence of the peaks is sorted, so you can give number p to show only the p most prominent peaks. Keep in mind, the 10 most prominent peaks do not necessarily mean the 10 highest peaks.

Comments and improvements are welcome.

Data: SO28173128.dat

# x    y
6.02   3.33
9.59   4.03
9.59   4.03
9.59   4.03
9.83   3.66
10.58   3.22
10.62   3.85
11.32   2.33
11.53   3.67
11.88   3.27
13.28   3.97
13.42   4.35
14.56   2.99
14.75   3.50
15.23   3.91
15.59   3.58
16.56   3.85
16.70   4.49
16.97   3.98
17.23   4.49
17.37   3.73
17.90   4.24
17.93   4.91
18.80   4.23
18.83   4.64
20.37   3.59
20.48   3.99
21.70   3.19
22.29   4.36
22.41   3.38
23.34   5.04
23.41   5.38
24.38   4.71
24.58   4.96
25.40   5.13
25.41   4.70
26.20   4.21
26.36   4.84
26.55   4.11
26.79   4.73
27.02   4.13
27.54   4.51
27.55   5.17
28.08   5.42
28.33   4.97
28.61   5.17
29.06   5.10
29.12   4.26
29.61   3.61
30.03   4.84
30.58   5.30
30.68   4.72
31.21   5.82
31.99   5.83
32.58   6.56
33.03   6.23
33.51   6.79
33.73   8.88
34.00   7.85
34.17   9.82
34.32   11.24
34.55   10.78
34.85   12.58
35.14   13.84
35.50   18.07
35.85   18.40
36.55   30.70
36.75   29.27
37.16   28.78
38.15   18.93
38.29   20.52
38.83   14.96
39.63   11.39
40.17   8.67
40.48   9.22
40.88   9.75
40.95   8.77
41.45   10.86
41.58   10.33
41.84   11.12
42.51   12.83
43.33   15.09
43.43   14.20
43.63   14.56
44.22   14.76
44.92   12.58
45.71   9.40
45.98   9.84
47.03   7.01
47.53   7.15
47.95   5.48
48.08   6.21
48.56   4.51
48.64   5.11
49.14   3.69
49.31   4.27
49.86   4.71
50.14   4.13
50.33   5.83
50.37   5.36
51.00   4.60
51.37   4.75
52.00   4.91
52.01   4.34
54.28   3.83
54.46   4.33
54.83   3.19
55.58   5.30
55.86   4.95
55.92   6.48
56.40   5.89
56.59   5.16
57.56   5.96
57.64   5.21
58.31   5.36
58.38   6.08
58.92   5.84
59.00   5.28
59.57   5.96
59.94   5.37
61.31   6.07
61.32   6.78
61.96   7.34
62.37   6.89
63.14   9.45
63.54   9.51
63.80   11.03
63.93   11.56
64.17   11.12
64.84   12.38
65.14   16.28
65.64   18.07
66.22   19.06
66.42   17.70
66.56   18.40
67.10   17.20
67.24   18.00
67.77   16.82
68.04   15.80
68.15   16.88
68.43   14.98
68.86   16.28
69.33   16.55
70.43   29.11
70.93   48.16
71.62   58.09
72.01   66.42
72.43   73.37
72.79   76.74
72.84   81.24
73.07   79.85
73.15   72.04
73.32   74.49
73.58   61.26
73.71   65.36
73.98   51.60
73.98   58.75
74.25   52.93
74.53   39.70
74.90   34.01
75.18   34.80
76.67   23.29
77.05   23.82
77.15   20.94
77.27   27.13
77.52   25.20
77.70   29.76
78.17   29.96
78.36   33.33
78.73   37.05
78.86   34.67
79.03   39.90
79.38   39.70
79.59   40.62
79.88   39.17
80.59   36.52
80.60   33.61
81.26   27.53
81.67   23.69
82.07   23.69
82.90   15.37
83.94   14.04
84.25   14.42
85.01   11.26
85.22   12.18
85.77   11.19
85.89   9.97
86.46   10.72
86.56   11.78
87.06   10.56
87.19   11.53
87.74   9.60
87.89   10.64
88.30   8.74
88.56   9.27
88.98   8.08
89.25   8.70
90.12   9.15
90.14   8.34
90.99   9.59
91.06   8.86
91.72   9.01
91.74   8.48
92.43   7.68
92.48   8.34
93.15   7.68
93.54   8.34
93.72   7.61
94.20   8.00
94.39   8.64
94.82   7.83
95.00   8.40
95.43   6.77
95.66   7.39
95.81   5.44
95.84   6.25
96.53   7.70
96.55   6.70
97.22   9.14
97.47   8.13
97.53   6.75
98.57   7.83
98.85   7.40
98.92   8.45
99.35   8.25
99.40   7.77
100.04   8.33
100.14   7.91
101.00   8.30
101.04   7.80
101.94   7.48
102.02   8.20
102.53   6.56
102.58   7.84
103.23   7.75
103.38   6.82
103.39   8.93
103.75   8.60
104.05   9.26
104.30   8.14
104.55   8.56
104.85   7.15
105.17   10.09
105.21   8.41
105.52   11.78
105.80   10.00
105.92   10.86
106.11   9.54
106.31   9.93
106.86   10.99
107.20   10.88
107.42   12.05
107.62   10.33
107.80   11.16
108.39   9.90
108.79   12.25
109.08   11.85
109.46   13.77
109.73   13.42
109.96   15.16
111.02   20.08
111.30   23.56
111.69   23.56
112.35   30.08
112.61   39.04
112.89   43.53
113.28   43.67
113.81   60.73
113.94   56.63
114.20   63.11
114.46   69.60
115.00   80.44
115.12   86.95
115.27   84.68
115.78   88.78
116.11   89.57
116.40   88.51
116.43   89.90
117.90   80.31
118.18   71.32
118.42   72.51
118.70   67.48
118.83   61.13
119.25   60.34
119.37   54.51
119.65   55.18
120.08   50.28
120.12   48.96
120.84   54.18
120.95   51.87
121.24   56.49
121.50   53.01
121.64   54.44
121.73   51.74
121.84   52.53
122.14   53.72
122.19   52.40
122.44   53.59
122.45   54.91
122.64   51.61
122.76   53.17
123.08   50.79
123.10   50.15
123.34   49.51
123.39   50.81
123.88   50.28
124.25   46.58
124.26   44.06
124.53   43.67
125.18   38.77
125.81   32.16
126.10   32.55
127.32   21.71
127.70   21.18
127.96   18.27
128.22   18.66
128.62   15.71
128.89   16.24
129.30   13.94
129.56   14.47
129.96   12.22
130.21   12.72
130.53   10.83
130.93   10.61
131.15   11.24
131.84   10.06
131.93   11.12
132.71   9.87
133.06   13.17
133.38   12.73
134.17   16.97
134.31   22.37
134.85   30.83
135.38   43.01
135.62   40.09
135.64   50.81
135.75   54.05
136.16   56.10
136.80   50.22
137.21   49.36
138.29   25.41
138.56   26.73
139.98   13.09
140.03   11.92
140.32   14.53
140.55   13.80
140.85   16.25
141.24   15.81
141.45   17.92
141.59   16.51
141.99   20.65
142.25   20.19
142.76   27.79
142.91   24.95
143.72   37.66
143.79   35.37
144.65   29.11
144.91   30.32
145.71   25.74
145.84   24.80
146.54   27.73
146.74   30.57
147.30   31.11
147.42   30.30
148.33   31.23
148.38   30.68
148.93   31.19
149.09   31.74
149.24   28.43
149.49   29.03
149.96   24.55
150.69   23.48
151.83   18.06
151.89   19.39
152.41   18.27
152.96   19.45
153.02   18.53
153.47   19.42
153.71   18.78
153.91   19.44
154.08   17.74
154.54   18.92
154.65   18.20
155.61   18.79
156.78   15.75
157.06   16.08
157.54   12.68
157.84   13.40
158.51   12.73
158.57   11.85
159.45   11.27
159.57   10.33
160.11   8.81
160.24   9.81
160.90   9.27
160.90   8.08
161.17   8.48
161.43   8.10
161.59   8.72
161.83   7.91
162.44   8.48
162.61   7.94
163.41   8.75
163.43   8.19
163.94   8.99
163.96   8.33
164.60   8.23
164.87   8.74
165.81   8.50
166.10   8.08
166.74   8.91
167.02   8.48
167.67   9.68
167.96   9.28
168.90   9.81
168.96   10.34
169.57   9.77
169.76   11.28
170.00   10.75
171.01   13.77
171.12   13.13
171.79   13.71
172.83   19.14
173.19   19.13
173.52   21.06
173.73   20.38
173.87   21.65
174.27   21.90
174.41   25.94
174.94   27.39
175.20   33.48
175.71   35.07
175.84   40.49
176.48   43.27
176.51   46.84
177.34   51.47
177.62   57.30
177.69   55.18
177.87   53.26
178.08   54.46
178.45   49.43
178.76   49.62
179.02   43.53
179.43   42.08
179.96   28.98
180.21   26.40
180.56   26.57
180.57   26.20
181.14   26.43
181.24   25.51
181.68   24.93
181.74   27.13
181.97   28.85
182.05   26.93
182.14   29.78
182.30   27.53
182.59   28.72
182.72   26.93
183.04   27.67
183.21   28.76
183.33   27.92
183.75   29.99
184.06   29.78
184.28   32.07
184.71   32.49
185.40   37.78
185.61   34.01
186.02   33.86
186.20   30.07
186.79   28.72
186.97   25.44
187.34   25.15
188.45   17.65
188.84   16.25
189.08   16.77
189.50   14.08
189.90   13.69
189.92   11.67
190.37   12.04
190.41   12.90
190.90   11.40
190.93   12.58
192.29   9.27
192.33   8.79
193.23   10.21
193.34   9.73
193.78   11.15
194.07   10.20
194.54   10.43
194.93   9.64
195.39   9.82
195.98   10.86
196.08   10.05
196.45   11.78
197.00   8.90
197.03   9.95
197.70   7.15
198.07   10.13
198.10   8.48
198.83   9.67
198.85   10.46
199.27   9.80
199.46   9.46
200.46   11.78
200.73   11.38
201.38   12.37
201.92   9.72
202.06   10.52
203.14   7.67
203.52   7.95
203.93   7.02
204.13   7.55
204.39   6.66
204.63   7.15
206.35   5.53
206.57   6.00
207.21   6.57
207.33   5.76
208.23   7.93
208.52   7.68
208.92   7.15
209.21   7.56
209.41   6.62
209.88   6.89
211.48   4.50
211.70   5.00
212.39   5.37
212.51   4.53
212.84   4.31
212.92   5.17
213.26   4.38
213.44   5.24
213.70   4.57
214.15   4.97
214.24   5.71
215.55   5.20
215.65   6.01
216.28   6.16
216.55   6.87
216.73   5.56
216.95   6.23
217.25   6.03
217.47   5.46
217.93   5.50
218.26   5.83
218.56   5.04
219.31   4.73
219.97   4.72
220.10   5.61
220.79   4.23
220.87   4.94
221.87   4.64
222.07   4.12
222.58   4.47
222.69   5.02
223.21   4.51
223.24   5.22
223.86   4.54
223.90   5.22
224.48   4.29
224.54   5.04
225.22   4.73
225.28   3.86
225.54   4.13
225.76   4.72
225.84   3.93
226.52   4.23
226.60   4.94
226.98   4.02
227.78   3.89
228.29   4.67
228.62   4.29
229.12   4.90
229.46   4.16
229.83   4.48
230.28   3.54
230.50   4.06
230.91   3.03
231.18   3.63
231.79   3.99
231.97   3.45
232.70   4.86

Script: (works with gnuplot>=5.4.0)

### a simple gnuplot peak finder (gnuplot>=5.4.0)
reset session

FILE = "SO28173128.dat"
colX = 1
colY = 2

# extract all peaks
set table $Peaks
    plot y2=y1=x2=x1=NaN FILE u \
         (x0=x1,x1=x2,x2=column(colX), y0=y1,y1=y2,y2=column(colY), \
         sprintf("%g %g",x1,y1)) w table if y0<y1 && y1>=y2 
unset table

isNaN(v) = v!=v         # check if value is NaN
min(a,b) = isNaN(a) && isNaN(b) ? NaN : isNaN(a) ? b : isNaN(b) ? a  : a<b ? a : b   # get minimum incl. NaN

# create prominence table
set print $Prominence
    do for [n0=0:|$Peaks|-1]  {
        xn = yn = xp = yp = NaN
        stats $Peaks u ($0<n0 && $2>y0 ? (xn=$1,yn=$2) : 0, \
                        $0>n0 && $2>y0 && yp!=yp ? (xp=$1,yp=$2) : 0, \
                        $0==n0+1 ? (x1=$1, y1=$2) : 0 ) nooutput
        print sprintf("%g %g %g",x0,y0, min(x0-xn,xp-x0))
        x0=x1
        y0=y1
    }
set print
set table $ProminenceSorted
    plot $Prominence u 1:2:(-$3) smooth zsort   # sort peaks by descending prominence
unset table

set key noautotitle
set offsets 0,0,1,0
set grid y

p = 10   # show number of peaks
set label 1 at graph 0.02,0.95 sprintf("%d most prominent peaks",p<|$Peaks| ? p : |$Peaks|)

plot FILE u colX:colY w l lc rgb "blue" ti "Spectrum", \
     $ProminenceSorted every ::::p-1 u 1:2 w impulses lc rgb "red", \
                    '' every ::::p-1 u 1:2:1 w labels offset 0,1
### end of script

Results: (for different p)

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.