93

Is there any way to iteratively retrieve data from multiple files and plot them on the same graph in gnuplot. Suppose I have files like data1.txt, data2.txt......data1000.txt; each having the same number of columns. Now I could write something like-

plot "data1.txt" using 1:2 title "Flow 1", \
     "data2.txt" using 1:2 title "Flow 2", \
      .
      .
      .
     "data1000.txt"  using 1:2 title "Flow 6"

But this would be really inconvenient. I was wondering whether there is a way to loop through the plot part in gnuplot.

mgilson
  • 300,191
  • 65
  • 633
  • 696
Slayer
  • 2,391
  • 4
  • 21
  • 18
  • Really cosy `bash` function in the [answer below](http://stackoverflow.com/a/34913776/3569208) – Hastur Jul 12 '16 at 18:34

6 Answers6

109

There sure is (in gnuplot 4.4+):

plot for [i=1:1000] 'data'.i.'.txt' using 1:2 title 'Flow '.i

The variable i can be interpreted as a variable or a string, so you could do something like

plot for [i=1:1000] 'data'.i.'.txt' using 1:($2+i) title 'Flow '.i

if you want to have lines offset from each other.

Type help iteration at the gnuplot command line for more info.

Also be sure to see @DarioP's answer about the do for syntax; that gives you something closer to a traditional for loop.

andyras
  • 15,542
  • 6
  • 55
  • 77
  • Thanks your solution "plot for [i=1:1000] 'data'.i.'.txt' using 1:2 title 'Flow '.i" worked for me.. I am using gnuplot 5.2 with C++ on Windows.... – MasoodRehman Aug 25 '17 at 06:47
  • But i have another problem, I am writing a program which write K number of files on hard disk from via fream K is a global variable so, I want to plot K number of files on my graph using gnuplot I tried for[i = 1:K] but it gives error of undefined variable. I tried outside for loop from gnuplot but that also does not work. – MasoodRehman Aug 25 '17 at 06:51
  • I wrote a function in C++ for gnuplot that works with for[i = 1:5] but when I use for for[i = 1:K] it gives error... – MasoodRehman Aug 25 '17 at 06:52
  • @MasoodUrRehman it sounds like you might be trying to use a variable from your C++ code in your gnuplot script; make sure you are printing the value of the variable K when you send commands to gnuplot. Gnuplot is saying 'undefined variable' because C++ knows what K is but gnuplot does not. If you are still stuck it might be good to post your issue as a separate C++ question. – andyras Aug 25 '17 at 13:36
95

Take a look also to the do { ... } command since gnuplot 4.6 as it is very powerful:

do for [t=0:50] {
  outfile = sprintf('animation/bessel%03.0f.png',t)
  set output outfile
  splot u*sin(v),u*cos(v),bessel(u,t/50.0) w pm3d ls 1
}

http://www.gnuplotting.org/gnuplot-4-6-do/

DarioP
  • 5,377
  • 1
  • 33
  • 52
  • 1
    Can I also use the iterator t to refer to an index in an array of for example file names or colors? – tommy.carstensen Sep 03 '13 at 11:53
  • 1
    I've never tried but I don't see any problem with that. Eventually the other possibility is to specify the array's items (colours, names or whatever) directly in the squared brackets, as shown in `help do`. – DarioP Sep 03 '13 at 12:03
  • 1
    I asked a new question here http://stackoverflow.com/questions/18591986/loop-over-array-in-gnuplot, because it is not obvious to me, how this can be achieved. – tommy.carstensen Sep 03 '13 at 12:14
11

I have the script all.p

set ...
...
list=system('ls -1B *.dat')
plot for [file in list] file w l u 1:2 t file

Here the two last rows are literal, not heuristic. Then i run

$ gnuplot -p all.p

Change *.dat to the file type you have, or add file types.

Next step: Add to ~/.bashrc this line

alias p='gnuplot -p ~/./all.p'

and put your file all.p int your home directory and voila. You can plot all files in any directory by typing p and enter.

EDIT I changed the command, because it didn't work. Previously it contained list(i)=word(system(ls -1B *.dat),i).

Jonatan Öström
  • 2,428
  • 1
  • 16
  • 27
10

Use the following if you have discrete columns to plot in a graph

do for [indx in "2 3 7 8"] {
  column = indx + 0
  plot ifile using 1:column ;  
}
Amit Ruhela
  • 311
  • 2
  • 8
2

I wanted to use wildcards to plot multiple files often placed in different directories, while working from any directory. The solution i found was to create the following function in ~/.bashrc

plo () {
local arg="w l"
local str="set term wxt size 900,500 title 'wild plotting'
set format y '%g'
set logs
plot"
while [ $# -gt 0 ]
        do str="$str '$1' $arg,"
        shift
done
echo "$str" | gnuplot -persist
}

and use it e.g. like plo *.dat ../../dir2/*.out, to plot all .dat files in the current directory and all .out files in a directory that happens to be a level up and is called dir2.

Jonatan Öström
  • 2,428
  • 1
  • 16
  • 27
  • You may add `plo() { [[ $# -eq 0 ]] && echo "Usage plo file1 file2 ..." || { .... } }` to avoid to call `gnuplot` without files. – Hastur Jul 12 '16 at 18:43
1

Here is the alternative command:

gnuplot -p -e 'plot for [file in system("find . -name \\*.txt -depth 1")] file using 1:2 title file with lines'
kenorb
  • 155,785
  • 88
  • 678
  • 743