For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > July 2006 > Sending data from perl to gnuplot and getting an "ASCII-art" graph back?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Sending data from perl to gnuplot and getting an "ASCII-art" graph back?
Adam Funk

2006-07-29, 6:58 pm

I'm generating some data points in a Perl program and trying to send
them to gnuplot and get back an "ASCII-art" graph (the kind that
gnuplot generates with the "set term dumb" setting). I'd like to
improve on the following steps:

(1)
foreach $x (sort {$a <=> $b} keys(%table) ) {
$y = $table{$x};
$line = sprintf("%5d %5d\n", $x, $y);
$max_y = $y if ($y > $max_y);
print($line) if ($option{v}); # verbose option
push(@output,$line);
}

This produces lines like this:
-5 2
-2 5

(2) Then I use recipe 7.5 from the Perl Cookbook to generate two temp
files, $data_file and $cmd_file, and I write @output from step (1)
into $data_file.

(3) Then I write a bunch of gnuplot commands as lines to $cmd_file:
set term dumb
set ylabel \"Frequency\"
set xlabel \"Time\"
unset key
set yrange [0:$max_y]
plot \"$temp_filename\" with impulses

(4) and call gnuplot thus:
system('gnuplot', $cmd_file);

The Perl program runs and prints the plot to the screen. I'm about to
modify it to use backticks
$gnuplot_output = `gnuplot $cmd_file`
but I can't believe there isn't a better way than what I've done to
send a list of commands to gnuplot and get the plot back.

Is there?

--
Thanks,
Adam
Theo Hopman

2006-07-29, 6:58 pm


Adam Funk wrote:
> I'm generating some data points in a Perl program and trying to send
> them to gnuplot and get back an "ASCII-art" graph (the kind that
> gnuplot generates with the "set term dumb" setting). I'd like to
> improve on the following steps:


I don't use Perl, but can offer some general suggestions.

> (1)
> foreach $x (sort {$a <=> $b} keys(%table) ) {
> $y = $table{$x};
> $line = sprintf("%5d %5d\n", $x, $y);
> $max_y = $y if ($y > $max_y);
> print($line) if ($option{v}); # verbose option
> push(@output,$line);
> }
>
> This produces lines like this:
> -5 2
> -2 5


Store this data in an array for later use.

> (2) Then I use recipe 7.5 from the Perl Cookbook to generate two temp
> files, $data_file and $cmd_file, and I write @output from step (1)
> into $data_file.


You should be able to avoid the use of temporary files entirely. See
below.

> (3) Then I write a bunch of gnuplot commands as lines to $cmd_file:
> set term dumb
> set ylabel \"Frequency\"
> set xlabel \"Time\"
> unset key
> set yrange [0:$max_y]
> plot \"$temp_filename\" with impulses


What you really want to do is pipe these commands to the stdin of
gnuplot. You also want to use inline data (see `help datafile
special-filenames`) like such:

plot "-" with impulses
-5 2
2 5
e

The data is supplied to gnuplot's stdin via the same pipe the commands
go through.

> (4) and call gnuplot thus:
> system('gnuplot', $cmd_file);
>
> The Perl program runs and prints the plot to the screen. I'm about to
> modify it to use backticks
> $gnuplot_output = `gnuplot $cmd_file`
> but I can't believe there isn't a better way than what I've done to
> send a list of commands to gnuplot and get the plot back.


I don't know how to do this in Perl, but in a shell script the
following would work (plus or minus the fact that I haven't done this
in a while):

gnuplot_output=`echo $gnuplot-commands-and-data | gnuplot`

THeo

Ethan Merritt

2006-07-29, 6:58 pm

In article <36tsp3-cm1.ln1@news.ducksburg.com>,
Adam Funk <a24061@yahoo.com> wrote:
>I'm generating some data points in a Perl program and trying to send
>them to gnuplot and get back an "ASCII-art" graph (the kind that
>gnuplot generates with the "set term dumb" setting). I'd like to
>improve on the following steps:
>
>(1)
> foreach $x (sort {$a <=> $b} keys(%table) ) {
> $y = $table{$x};
> $line = sprintf("%5d %5d\n", $x, $y);
> $max_y = $y if ($y > $max_y);
> print($line) if ($option{v}); # verbose option
> push(@output,$line);
> }
>
>This produces lines like this:
> -5 2
> -2 5


OK, although you could also just send this data directly to gnuplot.

>
>(2) Then I use recipe 7.5 from the Perl Cookbook to generate two temp
>files, $data_file and $cmd_file, and I write @output from step (1)
>into $data_file.


>(3) Then I write a bunch of gnuplot commands as lines to $cmd_file:
>set term dumb
>set ylabel \"Frequency\"
>set xlabel \"Time\"
>unset key
>set yrange [0:$max_y]
>plot \"$temp_filename\" with impulses
>
>(4) and call gnuplot thus:
> system('gnuplot', $cmd_file);


You can do that. But you could also do
it all in-line:

$gnuplot = '/usr/local/bin/gnuplot';

open(GNUPLOT, "| $gnuplot");
print GNUPLOT <<EOFgnuplot;
set term dumb
set output "plot.txt"
set ylabel "Frequency"
set xlabel "Time"
unset key
plot '' with impulses
EOFgnuplot

foreach $x (sort {$a <=> $b} keys(%table) ) {
... the stuff you were doing anyhow ...
printt GNUPLOT $line;
}
close(GNUPLOT);

Then you can copy the output in "plot.txt" to the screen
if you want, or dump it some other way.

--
Ethan A Merritt
Ben Morrow

2006-07-29, 6:58 pm


Quoth Adam Funk <a24061@yahoo.com>:
> I'm generating some data points in a Perl program and trying to send
> them to gnuplot and get back an "ASCII-art" graph (the kind that
> gnuplot generates with the "set term dumb" setting). I'd like to
> improve on the following steps:


Did you try http://search.cpan.org/search?query=gnuplot ? It shows up
two modules (Term::Gnuplot and Chart::Graph::Gnuplot) that look like
they may help.

Ben

--
The Earth is degenerating these days. Bribery and corruption abound.
Children no longer mind their parents, every man wants to write a book,
and it is evident that the end of the world is fast approaching.
Assyrian stone tablet, c.2800 BC benmorrow@tiscali.co.uk
Adam Funk

2006-07-30, 7:58 am

On 2006-07-29, Ethan Merritt <merritt@u.washington.edu> wrote:

> You can do that. But you could also do
> it all in-line:
>
> $gnuplot = '/usr/local/bin/gnuplot';
>
> open(GNUPLOT, "| $gnuplot");
> print GNUPLOT <<EOFgnuplot;
> set term dumb
> set output "plot.txt"
> set ylabel "Frequency"
> set xlabel "Time"
> unset key
> plot '' with impulses
> EOFgnuplot
>
> foreach $x (sort {$a <=> $b} keys(%table) ) {
> ... the stuff you were doing anyhow ...
> printt GNUPLOT $line;
> }
> close(GNUPLOT);
>
> Then you can copy the output in "plot.txt" to the screen
> if you want, or dump it some other way.


That's a good idea, but I think I'll try Theo's suggestion first,
since it should get gnuplot's output directly back into a variable in
the Perl program without needing a temp file.

Thanks.
Adam Funk

2006-07-30, 7:58 am

On 2006-07-29, Ben Morrow <benmorrow@tiscali.co.uk> wrote:

> Did you try http://search.cpan.org/search?query=gnuplot ?


Obviously not!

> It shows up two modules (Term::Gnuplot and Chart::Graph::Gnuplot)
> that look like they may help.


Interesting, but they look a bit heavy and oriented towards generating
graphics files. (I'll try to keep them in mind if I need to do that
later.)
Adam Funk

2006-07-30, 7:58 am

On 2006-07-29, Theo Hopman <hopman.theo@gmail.com> wrote:

> What you really want to do is pipe these commands to the stdin of
> gnuplot.


Exactly.

> You also want to use inline data (see `help datafile
> special-filenames`) like such:
>
> plot "-" with impulses
> -5 2
> 2 5
> e


I'd never come across this feature but it looks extremely useful...

> I don't know how to do this in Perl, but in a shell script the
> following would work (plus or minus the fact that I haven't done this
> in a while):
>
> gnuplot_output=`echo $gnuplot-commands-and-data | gnuplot`


....for this (which is about the same in Perl). Thanks!
Adam Funk

2006-07-30, 6:59 pm

On 2006-07-29, Theo Hopman <hopman.theo@gmail.com> wrote:

> What you really want to do is pipe these commands to the stdin of
> gnuplot. You also want to use inline data (see `help datafile
> special-filenames`) like such:
>
> plot "-" with impulses
> -5 2
> 2 5
> e

....
> gnuplot_output=`echo $gnuplot-commands-and-data | gnuplot`


The Perl equivalent of that works perfectly. Thanks!
Adam Funk

2006-07-31, 7:11 pm

On 2006-07-30, John W. Krahn <someone@example.com> wrote:

[color=darkred]
> You can probably do what you want with IPC::Open2 or Expect.
>
> perldoc IPC::Open2
> perldoc Expect


Those look quite useful, especially IPC::Open2 (which looks easier to
use).

I've got my program to work using Theo's suggestions, but I'll bear
those in mind for the future.

Thanks,
Adam
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com