2
votes

So I'm looking for some quick-and-dirty solution.

The problem:

I am trying to plot a specific section of a data file with gnuplot. This is fine. The basic line goes something like

plot "<(sed -n '1,100p' pointsandstuff.dat)" u 1:log($4**2+$5**2) notitle

This works just fine. The next step I want is to include in my title another part of the data, namely the data entry $3 (which for the points listed is identical, so I can parse it from anywhere). I run into problem because, while plot seems fine, I can't seem to feed regex info into 'title'. An example of something that doesn't work"

plot "<(sed -n '1,100p' pointsandstuff.dat)" u 1:log($4**2+$5**2) title "<(sed -n '1,1p' pointsandstuff.dat)"

(This would spit out a whole data line, in theory, though in practice I just get the title "<(sed...")

I tried attacking this with a bash script, but the '$'s that I use throw the bash script into a tizzy:

#!/bin/bash


STRING=$(echo|sed -n '25001,25001p' pointsandstuff.dat)
echo $STRING


 gnuplot -persist << EOF
 set xrange[:] noreverse nowriteback
 set yrange[:] noreverse nowriteback

 eval "plot "<(sed -n '25001,30000p' pointsandstuff.dat)" u 1:log($4**2+$5**2) title $STRING


EOF

Bash won't know what to do with '$4' and '$5'.

3

3 Answers

2
votes

You seem to be attempting process substitution, but the double quotes stop it working in the first case and you need a command substitution in the second case.

You have:

plot "<(sed -n '1,100p' pointsandstuff.dat)" u 1:log($4**2+$5**2) \
      title "<(sed -n '1,1p' pointsandstuff.dat)"

You need:

plot <(sed -n '1,100p' pointsandstuff.dat) u 1:log($4**2+$5**2) \
      title "$(sed -n '1,1p' pointsandstuff.dat)"

The double quotes in the second case might not be strictly necessary, but you won't go wrong with them present.

  • Process substitution generates a file name and feeds the output of the nested command into that file; the command thinks it is reading a file (because it is reading a file).

  • Command substitution captures the output of the nested command in a string and passes that string to the command (when it is used as an argument to a command, as here).

1
votes

My understanding of the question is a little hazy, but it looks like you want to plot the first 100 lines -- This is quite easy to do:

plot '< head -100 datafile.dat' u  ....

Of course, you can use sed if you wish (or awk or ...). A gnuplot only solution might look like this:

plot 'datafile.dat' u ($0 > 100? 1/0:$1):(log($4**2+$5**2))

Or like this (which is more simple for regular selections):

plot 'datafile.dat' every ::25001::30000 u 1:(log($4**2+$5**2)

and explained in more detail in another answer.

Now, if you want the title to come from the datafile, you can parse it out using gnuplot's backtic substitution:

plot ... title "`head -1 datafile.dat | awk '{print $3}'`"

which is essentially the same as gnuplot's system command:

plot ... title system("head -1 datafile.dat | awk '{print $3}'")

but in this case, you might be able to use the columnhead function:

plot ... title columnhead(3)
0
votes

Aha, thanks all. Have come up with a few solutions by now--the simplest being just escaping those $s from before (which I mistakenly thought gnuplot disliked...). To whit:

STRING=$(echo|sed -n '1,1p' spointsandstuff.dat)
echo $STRING


 gnuplot -persist << EOF
 set xrange[:] noreverse nowriteback
 set yrange[:] noreverse nowriteback

 eval "plot "<(sed -n '1,100p' pointsandstuff.dat)" u 1:(log(\$4**2+\$5**2)) title '$STRING'
 !gv diag_spec.eps &

EOF

Thanks all, though--it's been a good excuse to play with this stuff...here's hoping that, if any poor soul sees this script later, it might be a bit easier on them.