0

I normally use a code like following to pipe data from a file to gnuplot and create a picture during the Perl script:

#!/usr/bin/perl
use warnings;
use strict;

my $in="file.dat";

open(GP, "| gnuplot") or die "$!\n";
print GP << "GNU_EOF";

set terminal png size 1920,1080 font 'Verdana,15' dashed
set output 'out.png'
plot "$in"

GNU_EOF

close(GP);

I have to define "GNU_EOF" instead of 'GNU_EOF' so I can use variables like $in.

Now I want to use data which isn't read from a file directly. My code looks like:

#!/usr/bin/perl
use warnings;
use strict;

open(GP, "| gnuplot") or die "$!\n";
print GP << 'GNU_EOF';

set terminal png size 1920,1080 font 'Verdana,15' dashed
set output 'out.png'
plot '-'

GNU_EOF

open(INFILE,"< stuff.dat") or die "$!\n";
while (my $line = <INFILE>) {

for my $i (1..10){
    # do some stuff to calculate my data points stored in $x and $y
    print GP "$x $y\n";
}
print GP "EOF\n";
}

close(INFILE);
close(GP);

If I try this using "GNU_EOF" to be able to define variables in the heredoc, I am getting errors like:

gnuplot> 187 0.05
         ^
         line 1: invalid command

I don't know

  • why I have to use "" for the heredoc to get the desired variable expansion and

  • why I get errors for the second example.

Help is highly appreciated.

EverythingRightPlace
  • 1,197
  • 12
  • 33
  • 1
    My guess is that you need to pass something more than just the two coordinates to gnuplot. What does file.dat look like in your first example? – Dave Dec 06 '13 at 14:44
  • 2
    For me your example works fine without the line `print GP "EOF\n";` and with `pngcairo` (instead of `png` because of the `dashed` terminal option). – Christoph Dec 06 '13 at 14:48
  • @Christoph, You misread what I wrote because I fully know the error from was `gnuplot`. Anyway, I've already removed my comment for other reasons. – ikegami Dec 06 '13 at 15:16
  • @Christoph I need the line `print GP "EOF\n";` because I am using several loops to get data points. Nonetheless I tried it without this line (and only with one for-loop) which isn't solving the error. Neither pngcairo is a problem (I am also using pdf output, same error here). – EverythingRightPlace Dec 06 '13 at 15:17
  • 1
    @Christoph, The `print GP "EOF\n"` should not be removed. It tells `gnuplot`'s `plot` when to stop reading from `-`. (My version prompts me to use `e`, but `EOF` apparently works too.) – ikegami Dec 06 '13 at 15:17
  • 1
    The [Chart::Gnuplot](https://metacpan.org/pod/Chart::Gnuplot) module provides (incomplete) bindings to the gnuplot program, which might be preferable to templating the commands yourself. – amon Dec 06 '13 at 15:18
  • Correct, the line `print GP "EOF\n";` terminates `plot '-'`. So all the data which is sent after that, when the `while` loop continues, is interpreted as new commands. And gnuplot doesnt know commands like `187 0.05`. – Christoph Dec 06 '13 at 15:24
  • @Christoph Nothing is piped to Gnuplot during the `while` loop after the `print GP "EOF\n";` line. I set this line because otherwise the `print GP "$x $y\n"` wouldn't have an ending and Gnuplot wouldn't be able to handle upcoming numbers. Please see my answer I posted. I am looking forward to hear your thoughts because I don't completely understand it. – EverythingRightPlace Dec 06 '13 at 15:41
  • I thought you had a data file with several lines which you were going through. And as soon as you have more than one line in your `stuff.dat` you'll get the error with the script you have posted in the question. That shows the importance of minimal, but complete example ;) You were missing the content of `stuff.dat`, and the calculations of `$x` and `$y`, which made it difficult to track down your real problem (at least for me). – Christoph Dec 06 '13 at 15:51
  • @Christoph you are right, sorry for the bad example. I just didn't thought this would cause any problems. My `stuff.dat` has just one line with lots of columns. I want to plot several lines/graphs (using several `plot`) and therefore I have to re-structure the data. Nonetheless I have no clue why the line-break is problematic. – EverythingRightPlace Dec 06 '13 at 15:59
  • Maybe you need to escape the backslash as `\\ ` for use with `"GNU_EOF"`. – Christoph Dec 06 '13 at 16:43

1 Answers1

0

I solved it. Sorry for the incomplete question, I wanted to give a minimal example to avoid confusion. Unfortunately my question missed the important part. Like said in the comments I use several loops to generate data and pipe it to gnuplot:

#!/usr/bin/perl
use warnings;
use strict;

open(GP, "| gnuplot") or die "$!\n";
print GP << 'GNU_EOF';

set terminal png size 1920,1080 font 'Verdana,15' dashed
set output 'out.png'
plot    '-' t "one", \
        '-' t "two"

GNU_EOF

open(INFILE,"< stuff.dat") or die "$!\n";
while (my $line = <INFILE>) {

for my $i (1..10){
    # do some stuff to calculate data points stored in $x and $y
    print GP "$x $y\n";
}
print GP "EOF\n";
}

for my $i (1..50){
    # do some other stuff to calculate data points stored in $x and $y
    print GP "$x $y\n";
}
print GP "EOF\n";
}

close(INFILE);
close(GP);

I don't know why, but using 'GNU_EOF' (without variable expansion) I can define several plot with the line brake command \.

Using "GNU_EOF" I have to define it in one line:

plot '-' t "one", '-' t "two"

Sorry for the struggle, but maybe this is also helpful for someone else (and maybe you can explain this behaviour to me).

EverythingRightPlace
  • 1,197
  • 12
  • 33
  • 1
    `<<"X"` is like `"..."` and `<<'X'` is close to `'...'`. If you want to include a slash in a double-quoted string, you must escape it. – ikegami Dec 06 '13 at 17:40