1

After searching through all pipes to and inbuilt functions in gnuplot, I still haven't found a simple way to access the nth element of my datafile (not through increment, the single value) for use as a constant in a function (or parameter in a for loop) for my plots. For example I have a monotonic decreasing datafile with two columns and I want to normalize the y values while plotting so the y ranges from one (1) to zero (0) by subtracting the last value from each datapoint and dividing the subtraction by the difference between the first datapoint and the last. I tried awk but I'm not too familiar with the syntax. If there is a simple way I would love to know.

For example

plot "my2columndata.dat" using 1:(($2-'lastdatapoint')/('firstdatapoint'-'lastdatapoint'))

or something of the sorts where first and last datapoints are eponymous - they are the first and last datapoints in the monotonic decreasing datafile "my2columndata.dat"

user1880341
  • 13
  • 1
  • 4

3 Answers3

2

The idea is the same as @andyras 's, but using stats.

To answer the title, you can use every ::n::n, where n is the record (i.e. datapoint) number of choice. Records are numbered from 0, so if you want the first line, it should be every ::0::0. every can be used in either plot, splot, or stats (usage of every in stats is undocumented). I prefer stats since it doesn't plot anything, but it does clutter your gnuplot console (EDIT to avoid the cluttered console use nooutput at the end of the stats command). Also, you can use using to make arbitrary assingments.

For example, to save the second column of your first record,

stats "my2columndata.dat" u (firstdatapoint=$2) every ::0::0

Now to get the last record, you can use the number of records saved by stats, and use that as the record number in every,

stats "my2columndata.dat" # this saves the number of records to STATS_records
stats "my2columndata.dat" u (lastdatapoint=$2) every ::STATS_records-1::STATS_records-1

Now you can do the plot that you asked for.


And before I finish, some extra hacks:

Using mgilson's idea of counting columns, you can even save every column to a number of variables. (Note: I'm using shorthands u for using, and ev for every)

filename = "yourfilename.dat"
r = 0 # record number
good = 1
col = 1
while (good) {
 stats filename u (good=valid(col)) ev ::r::r
 if (good) {
  stats filename u col ev ::r::r
  eval(sprintf("v%d=STATS_max",col))
  col = col+1
 }
}

If the datafile contains 8 columns, then v1 to v8 are now defined.

But I suppose using an external tool is the right way to it (UNIX-likes can use tail/head etc.). Let's blame gnuplot authors for making this possible :)

gabri
  • 62
  • 8
syockit
  • 5,747
  • 1
  • 24
  • 33
1

In your case (since you know that the datafile is monotonically decreasing), this isn't too hard to do.

set terminal unknown
plot 'my2columndata.dat' # gather basic statistics
first=GPVAL_DATA_Y_MAX
last=GPVAL_DATA_Y_MIN

set terminal <whatever>
set output <whatever.wht>
plot 'my2columndata.dat' u 1:(($2-last)/(first-last))

This method gathers information about the datafile without creating an output, then replots using the GPVAL variables. (You can see this in gnuplot after plotting with the command show variables all.) In gnuplot 4.6.0 and above you can use the stats command to gather data without plotting as I have done here; stats creates different variable names though.

Accessing the n-th data point (as your question title hinted) would be trickier to do.

andyras
  • 15,542
  • 6
  • 55
  • 77
  • Thanks! This suits me perfectly and is simple I am curious to know how you could index the individual numbers but this certainly works! I'm reading up on similar commands. – user1880341 Dec 21 '12 at 23:05
0

Although the question is pretty old, in some cases it still might be necessary to get the first, nth or last value of a certain column. I know, that Linux users might use awk or other external programs, but the following is a platform independent gnuplot-only solution.

The difference of this solution to the existing answers from @andyras and @syockit:

  • works also for non-monotonically decreasing data
  • doesn't need stats
  • will also work with data having several empty lines (@syockit's solution might give wrong results)
  • returns also the nth data point.

Works also with gnuplot 4.6.0 (the time of OPs question).

Data: ("Data.dat")

# some comments
 0.1  0.2
 1.1  1.2
 2.1  2.2

 4.1  4.2
 5.1  5.2

 7.1  7.2


10.1 10.2
11.1 11.2

13.1 13.2
14.1 14.2


17.1 17.2

19.1 19.2
20.1 20.2

22.1 22.2

24.1 24.2
25.1 25.2

Code:

### get fist, nth and last datapoint of a column
reset

PointFirst = NaN
PointNth = NaN
PointLast = NaN
N=8

set terminal unknown
n=0
plot "Data.dat" u (n=n+1, n==1?PointFirst=$2:NaN, N==n?PointNth=$2:PointLast=$2)

print sprintf("First point:  %g",PointFirst)
print sprintf("% 2dth point:  %g",N,PointNth)
print sprintf("Last point:  %g",PointLast)
### end of code

Result:

First point:  0.2
 8th point:  11.2
Last point:  25.2
theozh
  • 22,244
  • 5
  • 28
  • 72