user431336
user431336

Reputation: 369

Can Gnuplot take different arguments at run time? maybe with Python?

I have 500 files to plot and I want to do this automatically. I have the gnuplot script that does the plotting with the file name hard coded. I would like to have a loop that calls gnuplot every iteration with a different file name, but it does not seem that gnuplot support command line arguments.

Is there an easy way? I also installed the gnuplot-python package in case I can do it via a python script.However, I couldn't find the api so it's a bit difficult to figure out.

Thank you!

Upvotes: 11

Views: 17036

Answers (8)

Anon
Anon

Reputation: 7144

Different methods of solving this problem are also covered in How to pass command line argument to gnuplot? :

  • Using -e
  • Using -c or call with ARG0 like variables (gnuplot >= 5)
  • Using call with $0 like variables (gnuplot <= 4.6.6)
  • Using environment variables and system()
  • Piping the program into gnuplot

Upvotes: 0

tcdaniel
tcdaniel

Reputation: 203

Unless I'm misunderstanding your question, there's an easier way.

In the gnuplot script, replace all occurrences of your filename with $0. Then in bash, loop over your plot files (let's say they are .txt files in $plotsDir) and call gnuplot:

for f in "$plotsDir/*.txt"; do
    echo "call '$f'" | gnuplot
done

Upvotes: 1

stringparser
stringparser

Reputation: 745

I've done this some times. But don't use EOF, because you cannot write on bash inside the << EOF and EOF tags. Depending on the names of the files you can do it in diferent ways.

a) If the filenames are loopable (sort of 1.dat 2.dat 3.dat, etc.)

#!/bin/bash    
for((i=0;i<1;i++)) do
  echo "plot '-' u 1:2"
  for((j=1;j<=3;j++)) do
     cat $i.dat
     echo "e"
  done
done | gnuplot -persist

The first loop is a kind of buffer to feed it all to gnuplot.

b) If the filenames aren't loopable (such as ñlasjkd.dat ajñljd.mov añlsjkd.gif) you first need to move them to a new folder. Then do

#!/bin/bash    

ffiles=$(ls | xargs)       # a list of the folder's files
# Use the list to pipe all the data to gnuplot using cat
for((i=0;i<1;i++)) do
  echo "plot '-' u 1:2 w lp"; 
  cat $ffiles; 
  echo "e"; 
done | gnuplot -persist

c) If you want some more, that is: to keep the information of the separated files just on one file... but maintaning the datasheets alive use "index" of gnuplot (if gnuplot reads two black lines guesses that is another datasheet)

#!/bin/bash

ffiles=$(ls|xargs)
ls $ffiles > ffiles.list # A file with the folder's files
while read line 
do
    cat $line; 
    echo -e; echo -e;
done < ffiles.list > alldata.dat 
# ^-feeding ffiles.list to the while loop 
# and writing the file alldata.dat

now you can go to gnuplot and acces to one datasheet

plot 'alldata.dat' index 1 u 1:2

and you will see the first file appearing on the list "ffiles.list". If you whant to see more than one, say 4

plot 'alldata.dat' index 1:4 u 1:2

tricky but easy.

Upvotes: 1

Sven Marnach
Sven Marnach

Reputation: 601421

You can transform your gnuplot script to a shell script by prepending the lines

#!/bin/sh
gnuplot << EOF

appending the line

EOF

and substituting every $ by \$. Then, you can substitute every occurence of the filename by $1 and call the shell script with the filename as parameter.

Upvotes: 22

Gab
Gab

Reputation: 326

Regarding the $'s in Sven Marnach's solution (the lines between EOF are called a "here script" in shell parlance): in my experience, one uses shell variables as usual, but $s that are meant for gnuplot itself must be escaped.

Here is an example:

for distrib in "uniform" "correlated" "clustered"
do
    gnuplot << EOF
    # gnuplot preamble omitted for brevity

    set output "../plots/$distrib-$eps-$points.pdf"
    set title "$distrib distribution, eps = $eps, #points = $points"

    plot "../plots/dat/$distrib-$eps-$points.dat" using 1:(\$2/$points) title "exact NN"
EOF

done

Note the backslash escaping the dollar so that gnuplot sees it.

Upvotes: 6

darioo
darioo

Reputation: 47183

I create a file named test.txt containing plot [0:20] x;

I run gnuplot test.txt and I see that gnuplot has indeed read contents of my file, so it does support arguments at runtime.

Upvotes: 0

nmichaels
nmichaels

Reputation: 50943

A simple way is to generate 500 gnuplot scripts like so:

for filename in list_of_files:
    outfile = open(filename + '-script', 'w')
    outfile.write(script_text % (filename,))

where script_text is the text of your gnuplot script with the filename replaced with a %s.

Upvotes: 1

Sven Marnach
Sven Marnach

Reputation: 601421

Here is one way to do this. Your gnuplot input file, say plot.gp, contains a line

plot "data"

or something like that. Save the lines before this line in plot1.gp and the lines after this line in plot2.gp. Now call gnuplot as

gnuplot plot1.gp -e `plot "data"` plot2.gp

which facilitates passing the name of data on the command line.

Upvotes: 0

Related Questions