1

The gnuplot stats command can be used to report stats for an input dataset. It creates a set of variables containing information about a specific column in the dataset. Here is an example of such use:

    set print "StatDat.dat" 
    do for [i=2:9] { # Here you will use i for the column.
      stats  'data.dat' u i nooutput ; 
      print i, STATS_median, STATS_mean , STATS_stddev # ...
    } 
    set print
    plot "StatDat.dat" us 1:2 # or whatever column you want...

It would be useful to include the reported column header, something like:

      print STATS_columnheader, STATS_median, STATS_mean , STATS_stddev # ...

However gnuplot does not provide the required STATS_columnheader variable.

Is there an alternative way to achieve this ?

starfry
  • 9,273
  • 7
  • 66
  • 96

3 Answers3

0

You can use an external tool such as awk to extract and return a column header. You can create a function like this:

columnheading(f,c) = system("awk '/^#/ {next}; {print $".c.";exit}' ".f)

which, given a file f and a column number c, will return the column header. You'd use it like this:

print columnheading('StatDat.dat',i).' ', STATS_median, STATS_mean , STATS_stddev # ...

The awk expression skips all lines until the first non-comment line, prints the word given by the c parameter and exits. The printed word is returned by gnuplots system command.

starfry
  • 9,273
  • 7
  • 66
  • 96
0

Workaround

A quick & dirty solution already expressed as comment to the answer here:
it is possible to store the header line once for all in a variable, then to call it when it is needed.

Under *nix it is possible to use head or a combination such head -n 10| tail -n 1 if it is in the 10th line...

Here the example modified:

firstrow = system('head -1 '.datafile)          # you call here only one time
set print "StatDat.dat" 
do for [i=2:9] {                                # Here you will use i for the column.
  stats datafile u i nooutput ; 
  print word(firstrow, i), " ", STATS_median, STATS_mean , STATS_stddev 
                                                # or whatever you want...
} 
set print
plot "StatDat.dat" us 1:2                       # or whatever column you want...

Note that the gnuplot function word will return the nth word in string, so you may have problem if the header is composed from more than a word...
... problems that you can overcome with other tricks

Only a path to a hack/trick

The following doesn't works because gnuplot starts to process the file in the plot command after skipping the header and the commented lines...

Since a function can assume the form f(x) = (statement1, statement2, statement3, return value) executing the statements and returning the value (see, e.g.), you can image to build a function that stores the first line "field by filed" in an array (directly form gnuplot 5.1, via some other tricks before), maybe hiding the plot with set terminal unknown.

array MyHeader[4]
f(x,y,z) = (x == 0 ? (MyHeader[y]=z, z ) : z)

set terminal unknown  # set terminal dumb
set key autotitle columnhead
do for [i=2:4] {                    # Here you will use i for the column.
  plot datafile using 1:(f($0,i,column(i)))
} 
print MyHeader

Unfortunately the above script stores only the 1st row values...
but for the moment I've finished the time I can dedicate to this problem :-(
(maybe someone can find useful some hint, or finish it).

Community
  • 1
  • 1
Hastur
  • 2,470
  • 27
  • 36
0

What exactly do you want to do with the headers?

As you can see in the plot command, apparently gnuplot considers the first uncommented line as header line which is then for example used for the legend.

No need for external tools or scripts. With stats you can also easily extract any line, e.g. the second line via every ::1::1. Since gnuplot 5.2.0 (Sep 2017) you can use arrays which you can also plot,e.g. for tables within the plot.

Script:

### extract header lines via stats
reset session

$Data <<EOD
# comment line
PosX    PosY   Density    # header line
  x/m   y/cm   g/cm2      # (sub)header line
  1     1.1    2.1
  2     1.2    2.2
  3     1.3    2.3
  4     1.4    2.4
  5     1.5    2.5
  6     1.6    2.6
  7     1.7    2.7
  8     1.8    2.8
  9     1.9    2.9
EOD

array Headers[3]
array Units[3]
do for [i=1:|Headers|] {
    stats $Data u (Headers[i]=strcol(i)) every ::0::0 nooutput
    stats $Data u (Units[i]  =strcol(i)) every ::1::1 nooutput
}
print Headers
print Units

set key top left
plot $Data u 1:2 w lp pt 7 lc "red"  ti columnheader, \
       ''  u 1:3 w lp pt 7 lc "blue" ti columnheader, \
       Headers u ($1+3):(2.1):2 w labels notitle, \
       Units   u ($1+3):(1.9):2 w labels notitle
### end of code

Result:

["PosX","PosY","Density"]

["x/m","y/cm","g/cm2"]

enter image description here

theozh
  • 22,244
  • 5
  • 28
  • 72