39

I want to create a gnuplot with three plots in it. The data should be inline (as I want to only

It should look like this:

https://s22.postimg.cc/qcc94e1i9/test.png

Currently I am using the following gnuplot script to create the plot:

set terminal png
set output "test.png"
plot for[col=2:4] "data.txt" using 1:col title columnheader(col) with lines

The file data.txt is:

Generation Best Worst Average
0 2 1 0
1 3 1 2
2 4 3 3
3 4 3 3
4 6 3 4
5 7 4 5
6 9 6 7
7 10 6 9
8 10 5 6
9 11 6 8
10 12 7 9

I would like to pipe the data.txt into gnuplot and not to rely on the referenced data file in the script. Something like cat data.txt | gnuplot plot.gnu. The reason for this is, that I have several data.txt files and don't want to build a plot.gnu file for each of these.

I read about the special '-' file in this stackoverflow thread and I read about multiple plots in one file. However this would require to include the data with the gnuplot code, which isn't clean.

Cœur
  • 37,241
  • 25
  • 195
  • 267

6 Answers6

32

If you are on a Unix system (i.e. not Windows) you can use '<cat' instead of '-' to read from stdin:

plot '<cat' using ...

Then you can do cat data.txt | gnuplot script.gp. However, in the specific case you mention in your question, with the plot in the for loop, you read the input three times. So sending the data through stdin is not appropriate, since the data will be gone after the first time it is read.

Dan Stahlke
  • 1,417
  • 1
  • 15
  • 20
28

not a direct answer but this is what i use to quickly look at data. it's especially helpful with the cut command

cat data.txt | cut -f2 -d' ' | gnuplot -p -e "plot '<cat'"
kirill_igum
  • 3,953
  • 5
  • 47
  • 73
  • Note though that you won't be able to manipulate the plot in any way: e.g. drag, resize — even simply maximizing the window will make gnuplot quit, because the data are no longer available. – Ruslan Oct 13 '19 at 08:49
  • Didn't crash for me. gnuplot --version --> gnuplot 5.2 patchlevel 8 – randompast Apr 26 '23 at 20:30
19

If you want to plot data coming from a pipe more than once, you need to store it somehow in memory. My preferred way is to use a temporary file in /dev/shm, which exists in most Linux systems and maps to RAM. Just to keep things clean, I set a trap to delete the temporary file at exit.

Example (using your data.txt):

cat data.txt | (cat > /dev/shm/mytempfile && trap 'rm /dev/shm/mytempfile' EXIT && gnuplot -e "set terminal dumb; plot for[col=2:4] '/dev/shm/mytempfile' using 1:col title columnheader(col) with lines")

Result:

12 ++------------+-------------+-------------+-------------+------------**
   +             +             +             +             + Best ****** +
   |                                                        Worst***#### |
10 ++                                              *******Average $$$$$$++
   |                                           ****                      |
   |                                        ***    $$$$               $$$$
 8 ++                                     **     $$    $$        $$$$$  ++
   |                                    **     $$        $$    $$        |
   |                               *****    $$$              $$       ####
 6 ++                          ****       $$ ############# $$    #####  ++
   |                         **         $$ ##             #  ####        |
   |                       **        $$$ ##                ##            |
   |                     **      $$$$  ##                                |
 4 ++         ***********   $$$$$  ####                                 ++
   |     *****  ###################                                      |
   | ****   $$##                                                         |
 2 **    $$$##                                                          ++
   #########                                                             |
   + $$          +             +             +             +             +
 0 $$------------+-------------+-------------+-------------+------------++
   0             2             4             6             8             10
Giancarlo Sportelli
  • 1,219
  • 1
  • 17
  • 20
  • 2
    Even nicer is to replace `set terminal dumb` with `set terminal dumb size $COLUMNS $LINES`, which takes current terminal size into account and stretches the output. – Ruslan Oct 13 '19 at 09:00
15

What's wrong with using the -e option of gnuplot from shell? You can provide a variable as input, say data.txt, from shell using:

gnuplot -e "filename='data.txt';ofilename='test.png'" plot.gnu

You should be able to call the above command multiple times with different values for "filename" from shell using a for loop.

And then you change your script plot.gnu to:

set terminal png
set output ofilename
plot for[col=2:4] filename using 1:col title columnheader(col) with lines
SidR
  • 2,964
  • 1
  • 18
  • 32
3

How about using the system() command

set terminal png
set output "test.png"

# read shell input
# the echo prints the variable, which is then piped to gnuplot
fname = system("read filename; echo $filename")

plot for[col=2:4] fname using 1:col title columnheader(col) with lines 

You can call it now with

echo "data.txt" | gnuplot script.gp
smoebius
  • 65
  • 4
-2

Mix both answers :

cat data.txt | gnuplot -e "set terminal png; set output "test.png"; plot for[col=2:4] '<cat' using 1:col title columnheader(col) with lines
  • 1
    This doesn't work, since reading from stdin can't be combined with a for loop in gnuplot. See http://stackoverflow.com/questions/4981279/how-to-make-several-plots-from-the-same-standard-input-data-in-gnuplot for workarounds. – ramn Dec 10 '13 at 15:41