#!/usr/bin/perl -w use strict; use Getopt::Long; use Time::HiRes qw( usleep ); use IO::Handle; use Data::Dumper; autoflush STDOUT 1; # list containing the plot data. Each element is a hash describing the extra # plotting options for each curve we're plotting, and the actual data to # plot for each curve. The length of this list grows as the data comes # in my @curves = (); # stream in the data by default # point plotting by default my %options = ( "stream" => 1, "points" => 0, "lines" => 0, "ymin" => "", "ymax" => "", "y2min" => "", "y2max" => ""); GetOptions(\%options, "stream!", "lines!", "points!", "legend=s@", "xlabel=s", "ylabel=s", "y2label=s", "title=s", "xlen=i", "ymin=f", "ymax=f", "y2min=f", "y2max=f", "y2=i@", "hardcopy=s", "help"); # set up plotting style my $style = ""; if($options{"lines"}) { $style .= "lines";} if($options{"points"}) { $style .= "points";} if(!$style) { $style = "points"; } sub usage { print "Usage: $0 \n"; print <) { foreach my $curve (@curves) { my $buf = $curve->{"data"}; # get the next datapoint, if there is one my $point; if(/($numRE)/gc) { $point = $1; } # if a point is not defined here, dup the last point we have if # possible elsif(@$buf) { $point = @$buf[$#$buf]; } # otherwise we can do nothing with this curve, so we skip it else { next; } # data buffering (up to stream sample size) push @$buf, $point; shift @$buf if(@$buf > $samples && $options{"stream"}); } # if any extra data is available, create new curves for it while(/($numRE)/gc) { newCurve("", "", $1); } plotStoredData($xlast, $samples, *PIPE) if($options{"stream"}); $xlast++; } if($options{"stream"}) { print PIPE "exit;\n"; close PIPE; } else { $samples = @{$curves[0]->{"data"}}; plotStoredData($xlast, $samples, *PIPE); if( defined $options{"hardcopy"}) { print PIPE "set output\n"; # sleep until the plot file exists, and it is closed. Sometimes the output is # still being written at this point usleep(100_000) until -e $temphardcopyfile; usleep(100_000) until(system("fuser -s $temphardcopyfile")); if($outputfileType eq "pdf") { system("ps2pdf $temphardcopyfile $outputfile"); } else { system("mv $temphardcopyfile $outputfile"); } printf "Wrote output to $outputfile\n"; return; } } sleep 100000; } sub plotStoredData { my ($xlast, $samples, $pipe) = @_; my $x0 = $xlast - $samples + 1; print $pipe "set xrange [$x0:$xlast]\n"; my @extraopts = map {$_->{"extraopts"}} @curves; print $pipe 'plot ' . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; foreach my $curve (@curves) { my $buf = $curve->{"data"}; # if the buffer isn't yet complete, skip the appropriate number of points my $x = $x0 + $samples - @$buf; for my $elem (@$buf) { print $pipe "$x $elem\n"; $x++; } print PIPE "e\n"; } } sub newCurve() { my ($title, $opts, $newpoint) = @_; if($title) { $opts = "title \"$title\" $opts" } else { $opts = "notitle $opts" } my $data = []; if (defined $newpoint) { my $numpoints = 1; if (@curves) { $numpoints = @{$curves[0]->{"data"}}; } $data = [($newpoint) x $numpoints] } push ( @curves, {"extraopts" => " $opts", "data" => $data} ); } main;