M. Toya
M. Toya

Reputation: 715

Plotting columns by calling their header with GnuPlot

I have file of this format:

x y1 y2 y3 ei1 ei2 ei3 es1 es2 es3
1 4 5 4 7 7 2 4 7 7
2 7 3 3 3 8 3 3 3 8
3 2 1 4 4 9 6 4 4 9

I want to produce plots similar to what the following command would give

plot "filename" using 1:2:5:8  with yerrorbars

but using the columns headers(x, y1, ei1 and es1) to call them. How can this be done?

Page 84 of the gnuplot manual (documenting the using command) reads:

Height Weight Age
val1   val1   val1
...    ...    ...

then the following plot commands are all equivalent

plot ’datafile’ using 3:1, ’’ using 3:2

plot ’datafile’ using (column("Age")):(column(1)), \
’’ using (column("Age")):(column(2))

plot ’datafile’ using "Age":"Height", ’’ using "Age":"Weight"

However when I tried them I only got the row indices versus themselves.

Upvotes: 8

Views: 8074

Answers (1)

mgilson
mgilson

Reputation: 310307

Taking a quick look at the documentation for gnuplot 4.4 vs gnuplot 4.6 (current stable release), it appears that the feature you are trying to use was probably introduced in gnuplot 4.5 (Odd numbers are the development branches -- when they are deemed stable, they get incremented to an even number). The only way that can think of to accomplish this is to write a simple script in some other language which returns the column number (to stdout). Here's a simple example using python although I'm positive that you could do this in awk if you wanted to remain in an all-POSIX environment:

#python indexing is 0 based, gnuplot datafile indexing 1 based
COL_AGE=`python -c 'print(open("datafile").readline().split().index("AGE")+1)'`
COL_HEIGHT=`python -c 'print(open("datafile").readline().split().index("HEIGHT")+1)'`
plot "datafile" u COL_AGE:COL_HEIGHT

This little script doesn't do anything fancy (It assumes the column headers are on the first line for example), but using the power of python, it would be pretty easy to extend the script further:

#!/usr/bin/env python
import sys
with open(sys.argv[1]) as f
   for line in f:
       if (line.strip()):
           print (line.split().index(sys.argv[2])+1)
           sys.exit(0)

Now you can call this script as: python script.py datafile AGE to find out which column "AGE" is in. It is an error if "AGE" isn't in any column.

Upvotes: 6

Related Questions