Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Running (real-)time series plots with gnuplot?

by RMGir (Prior)
on Sep 10, 2002 at 14:31 UTC ( #196684=perlquestion: print w/replies, xml ) Need Help??

RMGir has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to plot data as it arrives in realtime with gnuplot.

I've arrived at a fairly simple perl solution, but it involves writing the data to a temporary file and then replotting the whole file every second.

I'm afraid this will result in too much overhead towards the end of the day, as the number of data points accumulates.

I have a perl implementation of my approach, and I'd like suggestions from any gnuplot gurus out there as to more efficient ways to do this.

I've looked at Chart::Graph::Gnuplot, and looked at a few gnuplot related nodes here, but I don't think they solves this problem.

Here's a dummy data source. In reality, this could take input from anything that outputs a time and a value.

#!/usr/bin/perl -w use strict; use POSIX qw(strftime); my $value=rand(100); $|=1; while(1) { sleep(1); print strftime("%H:%M:%S",localtime),",$value\n"; # jitter the value $value+=rand(2)-1; }
Here's the actual gnuplot-calling code. This assumes gnuplot is on your path, and that you have File::Temp installed.

If you don't have File::Temp, it should be simple to adjust the script to use a fixed file name.

#!/usr/bin/perl -w use strict; use File::Temp qw(tempfile tempdir); use IO::Handle; my $tempdir=tempdir(CLEANUP=>1); my ($plotFh, $plotFilename)=tempfile(DIR=>$tempdir); # replace this with whatever the real data src is if needed open(DATASRC,"perl|") or die "Can't run data source, error +$!"; open(GNUPLOT,"|gnuplot"); $plotFh->autoflush(1); select GNUPLOT; $|=1; # set up plot options for time series graph print GNUPLOT "set xdata time\n"; print GNUPLOT q(set timefmt "%H:%M:%S"),qq(\n); my $prevTime=""; my $prevValue=0; while(<DATASRC>) { chomp; my ($time, $value)=split /,/; if($time ne $prevTime) { if($prevTime ne "") { print $plotFh "$prevTime $prevValue\n"; print GNUPLOT "plot '$plotFilename' using 1:2\n"; } $prevTime=$time; } $prevValue=$value; }
Any ideas?


Replies are listed 'Best First'.
Re: Running (real-)time series plots with gnuplot?
by RMGir (Prior) on Sep 10, 2002 at 19:54 UTC
    In case anyone's curious, the solution turned out to be making that script a bit more general so it can handle any number of time series on STDIN, and limiting the number of datapoints plotted to 900, giving 15 minutes of back history on the graph.

    Once more than 900 data points have arrived, the file is rewritten every second to hold only the last 900 points.

    That keeps the performance costs pretty reasonable; once all 15 minutes are displayed, the CPU cost on a dual-processor Linux box is about 1% CPU usage per series.

    Edit: 2003-01-21: It turns out that setting

    gnuplot.raise: False
    in .Xresources makes gnuplot behave MUCH better; it stops popping up in front of other windows with each data point.
Re: Running (real-)time series plots with gnuplot?
by RMGir (Prior) on Sep 10, 2002 at 14:34 UTC
    (hmmm, it'd be nice to be able to edit SOPW nodes)

    It may be obvious, but the first perl script should be saved as

    The 2nd is the script that you run from the command line, so you can name it whatever you like. I called it

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://196684]
Approved by krisahoch
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (9)
As of 2023-03-20 13:22 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (59 votes). Check out past polls.