Here are two ways for plotting data on-the-fly.
Looping with gnuplot
You must call plot
over and over again, the data is preprocessed by an external script. The minimal gnuplot script filter.gp
is:
while (1) {
plot '< ./myscript.pl' using 2:1
pause 1
}
To stop this, hit Ctrl+C
.
The Perl script for the preprocessing may look like the following myscript.pl
:
#!/usr/bin/perl
use strict;
use warnings;
my $path = "file.log";
my @grepped;
my $t = 0;
open(INFILE,"< $path") or die "$! \n";
while (my $line = <INFILE>) {
if ($line =~ m{^Time = (\d+)}){
$t = $1;
};
if ($line =~ m{^Errors: local = (\d+), global = (\d+)}){
print "$t\t$1\t$2\n";
};
};
close(INFILE);
Just run it with gnuplot filter.gp
.
To make it more configurable, one can change the script to use a variable which is passed to gnuplot via the command line:
while (1) {
plot '< ./myscript.pl -f '.path using 2:1
pause 1
}
or use reread
for this:
plot '< ./myscript.pl -f '.path using 2:1
pause 1
reread
Call this script with gnuplot -e "path='file.log';" filtermod.gp
.
That works, but would filters the complete file over and over again.
Piping from Perl to gnuplot
Here is a Perl script, which basically works for me, but its my first real Perl script, so there may be some nonideal parts. Feel free to comment on that.
#!/usr/bin/perl
use strict;
use warnings;
my $path = "file.log";
my @grepped;
my $switch = "off";
open(my $gp, "| gnuplot -persist") or die "$! \n";
$gp->autoflush(0);
use File::Tail;
my $file = File::Tail->new(name=>$path, maxinterval=>1, tail=>-1);
while (defined(my $line= $file->read)) {
if ($line =~ m{^Time = (\d+)}){
push(@grepped,"$1\t");
};
if ($line =~ m{^Errors: local = (\d+), global = (\d+)}){
push(@grepped,"$1\t");
push(@grepped,"$2\n");
$switch = "refresh";
};
if ($switch eq "refresh") {
print $gp <<"GNU_EOF";
plot '-' using 2:1
@grepped
e
GNU_EOF
$gp->flush;
$switch = "off";
};
Time::HiRes::sleep(0.1);
};
What I found to be important here is
- Looping over a changing file.
- The arrangement of the
autoflush
andflush
. - The
sleep
to allow gnuplot to process the data properly.
That worked for a very small test data file. Don't know if it will for a larger one as well, but should help you a bit further.