Accessing the nth datapoint in a datafile using gnuplot

gnuplot

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"

Best Answer

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 :)

Related Topic