Alfe
Alfe

Reputation: 59516

Generate Gnuplot Datablock by Shell command

I have a rather costly shell command which generates some output which is supposed to be plotted. The output contains information for several curves, e. g. like this:

echo 1 2 3; echo 4 5 6; echo 7 8 9

They are supposed to be plotted using a command like this:

plot <something> using 1:2, \
     <something> using 1:3

To avoid calling the shell command repeatedly (as it is rather slow), I want to store its result in a datablock, but up to now my trials didn't work. Here is what I tried:

output = system("echo 1 2 3; echo 4 5 6; echo 7 8 9")
set print $DATA
print output
unset print

Now I seem to have a datablock containing what I want because print $DATA now prints this:

1 2 3
4 5 6
7 8 9
   

The trailing blank line I hope isn't a problem but maybe it indicates that there is something wrong, I don't know.

When I now try to plot this with plot $DATA using 1:2 I only get the first of the three expected points (1|2), (4|5), and (7|8).

I feel there is probably an easier way to achieve my original goal but up to now I didn't find it.

Upvotes: 0

Views: 390

Answers (2)

maij
maij

Reputation: 4218

Now I seem to have a datablock containing what I want because print $DATA now prints this:

1 2 3
4 5 6 
7 8 9 

No, $DATA does not contain what you want. $DATA should be an array with three elements: 1st element is 1 2 3, 2nd element is 4 5 6, and 3rd one is 7 8 9. Instead, the combination of output = system("..."), set print $DATA, and print output generates an array with only one element: 1 2 3\n4 5 6\n7 8 9, printing into a datablock does not split the string into separate lines.

The difference is not visible with print $DATA. Both, a new array element of the datablock as well as a \n within an array element generate a linebreak.

You can use the load '< XXXXX' command to generate a useful datablock. From the gnuplot documentation:

The load command executes each line of the specified input file as if it had been typed in interactively.

...

On some systems which support a popen function (Unix), the load file can be read from a pipe by starting the file name with a '<'.

The "XXXXX" can be a series of shell commands which generate the necessary gnuplot commands:

load '< echo "\$DATA << EOD" && echo 1 2 3; echo 4 5 6; echo 7 8 9 && echo "EOD"'
print $DATA
plot $DATA using 1:2 pt 5, $DATA using 1:3 pt 7 

(inspired by gnuplot: load datafile 1:1 into datablock)

Upvotes: 2

theozh
theozh

Reputation: 25988

Assuming I understood your problem correctly, I see three versions where versions 2 and 3 should work. I guess version 2 is what you wanted to avoid. Why the 1st version does not work I only can guess. My suspicion is something with the line end character. There seems to be a difference if you write to a datablock (version 1) or to a file (version 3). I remember a discussion with @Ethan about this... but I still don't understand myself. I assume you're working with Linux, in Windows & is used instead of ;.

Code:

### system output to datablock
reset session

# Version 1
set title "Version 1: only plots 1st data line"
output = system("echo 1 2 3 & echo 4 5 6 & echo 7 8 9")   # in Windows "&" instead of ";"
set print $Data
    print output
set print
plot $Data u 1:2 w lp pt 7
pause -1

# Version 2
set title "Version 2: several system calls"
set print $Data
    print system("echo 1 2 3")
    print system("echo 4 5 6")
    print system("echo 7 8 9")
set print
plot $Data u 1:2 w lp pt 7
pause -1

# Version 3
set title "Version 3: writing into data file"
output = system("echo 1 2 3 & echo 4 5 6 & echo 7 8 9")   # in Windows "&" instead of ";"
set print "Data.dat"
    print output
set print
plot "Data.dat" u 1:2 w lp pt 7

### end of code

Upvotes: 1

Related Questions