From 704c3f16074ce74add9e0c8681ccac9eb3b27f16 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 19 Dec 2009 20:46:06 -0800 Subject: [PATCH 001/270] added realtime gnuplot script from http://users.softlab.ece.ntua.gr/~ttsiod/gnuplotStreaming.html --- driveGnuPlots.pl | 104 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 driveGnuPlots.pl diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl new file mode 100755 index 0000000..82ed79f --- /dev/null +++ b/driveGnuPlots.pl @@ -0,0 +1,104 @@ +#!/usr/bin/perl -w +use strict; + +sub usage { + print "Usage: $0 \n"; + print < ...per stream2... +... + ...per streamN... + Stream1_YRangeMin Stream1_YRangeMax Min and Max values for stream 1 + Min and Max values for stream 2 +... + Min and Max values for stream N + +OEF + exit(1); +} + +sub Arg { + if ($#ARGV < $_[0]) { + print "Expected parameter missing...\n\n"; + usage; + } + $ARGV[int($_[0])]; +} + +sub main { + my $argIdx = 0; + my $numberOfStreams = Arg($argIdx++); + print "Will display $numberOfStreams Streams (in $numberOfStreams windows)...\n"; + my @sampleSizes; + for(my $i=0; $i<$numberOfStreams; $i++) { + my $samples = Arg($argIdx++); + push @sampleSizes, $samples; + print "Stream ".($i+1)." will use a window of $samples samples\n"; + } + my @ranges; + for(my $i=0; $i<$numberOfStreams; $i++) { + my $miny = Arg($argIdx++); + my $maxy = Arg($argIdx++); + push @ranges, [ $miny, $maxy ]; + print "Stream ".($i+1)." will use a range of [$miny, $maxy]\n"; + } + my @gnuplots; + my @buffers; + shift @ARGV; # number of streams + for(my $i=0; $i<$numberOfStreams; $i++) { + shift @ARGV; # sample size + shift @ARGV; # miny + shift @ARGV; # maxy + local *PIPE; + open PIPE, "|gnuplot" || die "Can't initialize gnuplot number ".($i+1)."\n"; + select((select(PIPE), $| = 1)[0]); + push @gnuplots, *PIPE; + print PIPE "set xtics\n"; + print PIPE "set ytics\n"; + print PIPE "set yrange [".($ranges[$i]->[0]).":".($ranges[$i]->[1])."]\n"; + print PIPE "set style data linespoints\n"; + print PIPE "set grid\n"; + my @data = []; + push @buffers, @data; + } + my $streamIdx = 0; + select((select(STDOUT), $| = 1)[0]); + my $xcounter = 0; + while(<>) { + chomp; + my $buf = $buffers[$streamIdx]; + my $pip = $gnuplots[$streamIdx]; + + # data buffering (up to stream sample size) + push @{$buf}, $_; + #print "stream $streamIdx: "; + print $pip "set xrange [".($xcounter-$sampleSizes[$streamIdx]).":".($xcounter+1)."]\n"; + print $pip "plot \"-\" notitle\n"; + my $cnt = 0; + for my $elem (reverse @{$buf}) { + #print " ".$elem; + print $pip ($xcounter-$cnt)." ".$elem."\n"; + $cnt += 1; + } + #print "\n"; + print $pip "e\n"; + if ($cnt>=$sampleSizes[$streamIdx]) { + shift @{$buf}; + } + $streamIdx++; + if ($streamIdx == $numberOfStreams) { + $streamIdx = 0; + $xcounter++; + } + } + for(my $i=0; $i<$numberOfStreams; $i++) { + my $pip = $gnuplots[$i]; + print $pip "exit;\n"; + close $pip; + } +} + +main; From cc96aac692692a5553ade9bef9eb085b484dda94 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 23 Jan 2009 16:56:57 -0800 Subject: [PATCH 002/270] realtime gnuplot driver: one window, multiple plots darcs-hash:20090124005657-0cb85-b53c7089a73ae521f3417e1871d68f31bcb78f7b.gz --- driveGnuPlots.pl | 125 +++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 82ed79f..9e64af0 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -6,15 +6,9 @@ sub usage { print < ...per stream2... -... - ...per streamN... - Stream1_YRangeMin Stream1_YRangeMax Min and Max values for stream 1 - Min and Max values for stream 2 -... - Min and Max values for stream N + NumberOfStreams How many streams to plot + Stream_WindowSampleSize this many samples + Stream_YRangeMin Stream_YRangeMax Min and Max y values OEF exit(1); @@ -28,77 +22,82 @@ sub Arg { $ARGV[int($_[0])]; } +sub plotHeader +{ + my ($xcounter, $samples, $numberOfStreams, $pipe) = @_; + #print "stream $streamIdx: "; + print $pipe "set xrange [".($xcounter-$samples).":".($xcounter+1)."]\n"; + print $pipe 'plot ' . join(', ' , ('"-" notitle') x $numberOfStreams) . "\n"; +} + sub main { my $argIdx = 0; my $numberOfStreams = Arg($argIdx++); - print "Will display $numberOfStreams Streams (in $numberOfStreams windows)...\n"; - my @sampleSizes; - for(my $i=0; $i<$numberOfStreams; $i++) { - my $samples = Arg($argIdx++); - push @sampleSizes, $samples; - print "Stream ".($i+1)." will use a window of $samples samples\n"; - } - my @ranges; - for(my $i=0; $i<$numberOfStreams; $i++) { - my $miny = Arg($argIdx++); - my $maxy = Arg($argIdx++); - push @ranges, [ $miny, $maxy ]; - print "Stream ".($i+1)." will use a range of [$miny, $maxy]\n"; - } - my @gnuplots; + print "Will display $numberOfStreams Streams...\n"; + + my $samples = Arg($argIdx++); + print "Will use a window of $samples samples\n"; + + my $miny = Arg($argIdx++); + my $maxy = Arg($argIdx++); + print "Will use a range of [$miny, $maxy]\n"; + my @buffers; shift @ARGV; # number of streams + shift @ARGV; # sample size + shift @ARGV; # miny + shift @ARGV; # maxy + local *PIPE; + + open PIPE, "|gnuplot" || die "Can't initialize gnuplot\n"; + + select((select(PIPE), $| = 1)[0]); + print PIPE "set xtics\n"; + print PIPE "set ytics\n"; + print PIPE "set yrange [". $miny . ":" . $maxy ."]\n"; + print PIPE "set style data points\n"; + print PIPE "set grid\n"; + for(my $i=0; $i<$numberOfStreams; $i++) { - shift @ARGV; # sample size - shift @ARGV; # miny - shift @ARGV; # maxy - local *PIPE; - open PIPE, "|gnuplot" || die "Can't initialize gnuplot number ".($i+1)."\n"; - select((select(PIPE), $| = 1)[0]); - push @gnuplots, *PIPE; - print PIPE "set xtics\n"; - print PIPE "set ytics\n"; - print PIPE "set yrange [".($ranges[$i]->[0]).":".($ranges[$i]->[1])."]\n"; - print PIPE "set style data linespoints\n"; - print PIPE "set grid\n"; - my @data = []; - push @buffers, @data; + my @data = []; + push @buffers, @data; } + my $streamIdx = 0; select((select(STDOUT), $| = 1)[0]); my $xcounter = 0; + plotHeader($xcounter, $samples, $numberOfStreams, *PIPE); while(<>) { chomp; - my $buf = $buffers[$streamIdx]; - my $pip = $gnuplots[$streamIdx]; - - # data buffering (up to stream sample size) - push @{$buf}, $_; - #print "stream $streamIdx: "; - print $pip "set xrange [".($xcounter-$sampleSizes[$streamIdx]).":".($xcounter+1)."]\n"; - print $pip "plot \"-\" notitle\n"; - my $cnt = 0; - for my $elem (reverse @{$buf}) { + my $line = $_; + foreach my $point ($line =~ /([-]?[0-9\.]+)/g) + { + my $buf = $buffers[$streamIdx]; + + # data buffering (up to stream sample size) + push @{$buf}, $point; + + my $cnt = 0; + for my $elem (reverse @{$buf}) { #print " ".$elem; - print $pip ($xcounter-$cnt)." ".$elem."\n"; - $cnt += 1; - } - #print "\n"; - print $pip "e\n"; - if ($cnt>=$sampleSizes[$streamIdx]) { + print PIPE ($xcounter-$cnt)." ".$elem."\n"; + $cnt++; + } + #print "\n"; + print PIPE "e\n"; + if ($cnt>=$samples) { shift @{$buf}; - } - $streamIdx++; - if ($streamIdx == $numberOfStreams) { + } + $streamIdx++; + if ($streamIdx == $numberOfStreams) { $streamIdx = 0; $xcounter++; - } - } - for(my $i=0; $i<$numberOfStreams; $i++) { - my $pip = $gnuplots[$i]; - print $pip "exit;\n"; - close $pip; + plotHeader($xcounter, $samples, $numberOfStreams, *PIPE); + } + } } + print PIPE "exit;\n"; + close PIPE; } main; From 6d2c3ccd0bfa00958a0b634ca45639ea6ab4809b Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 4 Feb 2009 13:22:03 -0800 Subject: [PATCH 003/270] drivegnuplots: tabs->spaces. whitespace modifications only Ignore-this: 8f3c72e2b8ce91f6eb13d7c6db6e38f2 darcs-hash:20090204212203-0cb85-8f340682a9daae2825be0b6a3dc743e5434b13f9.gz --- driveGnuPlots.pl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 9e64af0..00c3cbc 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -16,8 +16,8 @@ OEF sub Arg { if ($#ARGV < $_[0]) { - print "Expected parameter missing...\n\n"; - usage; + print "Expected parameter missing...\n\n"; + usage; } $ARGV[int($_[0])]; } @@ -68,7 +68,7 @@ sub main { my $xcounter = 0; plotHeader($xcounter, $samples, $numberOfStreams, *PIPE); while(<>) { - chomp; + chomp; my $line = $_; foreach my $point ($line =~ /([-]?[0-9\.]+)/g) { @@ -79,19 +79,19 @@ sub main { my $cnt = 0; for my $elem (reverse @{$buf}) { - #print " ".$elem; - print PIPE ($xcounter-$cnt)." ".$elem."\n"; - $cnt++; + #print " ".$elem; + print PIPE ($xcounter-$cnt)." ".$elem."\n"; + $cnt++; } #print "\n"; print PIPE "e\n"; if ($cnt>=$samples) { - shift @{$buf}; + shift @{$buf}; } $streamIdx++; if ($streamIdx == $numberOfStreams) { - $streamIdx = 0; - $xcounter++; + $streamIdx = 0; + $xcounter++; plotHeader($xcounter, $samples, $numberOfStreams, *PIPE); } } From bb9a00994ce7159304f7728d3d3291af5632c42e Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 4 Feb 2009 13:39:24 -0800 Subject: [PATCH 004/270] drivegnuplots: only output the header if we've data for this data set Ignore-this: effce8f31a4e9d8272927ed9faaf92c1 darcs-hash:20090204213924-0cb85-17f735f088325e37142d41dd987212c90e343950.gz --- driveGnuPlots.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 00c3cbc..e3e0f07 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -66,10 +66,10 @@ sub main { my $streamIdx = 0; select((select(STDOUT), $| = 1)[0]); my $xcounter = 0; - plotHeader($xcounter, $samples, $numberOfStreams, *PIPE); while(<>) { chomp; my $line = $_; + plotHeader($xcounter, $samples, $numberOfStreams, *PIPE) if($streamIdx == 0); foreach my $point ($line =~ /([-]?[0-9\.]+)/g) { my $buf = $buffers[$streamIdx]; @@ -92,7 +92,6 @@ sub main { if ($streamIdx == $numberOfStreams) { $streamIdx = 0; $xcounter++; - plotHeader($xcounter, $samples, $numberOfStreams, *PIPE); } } } From 855a0d558331a9a1d491eccdcda97b4d242fd036 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 9 Feb 2009 01:35:19 -0800 Subject: [PATCH 005/270] drivegnuplot: style on the cmdline Ignore-this: 6b20c61ec03965d0a090ee8f2475b45b darcs-hash:20090209093519-0cb85-bdcbd0698f84ea6830931bf4c0cc314a2bde9824.gz --- driveGnuPlots.pl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index e3e0f07..677c35e 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -1,5 +1,15 @@ #!/usr/bin/perl -w use strict; +use Getopt::Long; + +# point plotting by default +my %options = ( "lines" => 0); +GetOptions(\%options, + "lines!"); + +# set up plotting style +my $style = "points"; +$style = "linespoints" if($options{"lines"}); sub usage { print "Usage: $0 \n"; @@ -55,7 +65,7 @@ sub main { print PIPE "set xtics\n"; print PIPE "set ytics\n"; print PIPE "set yrange [". $miny . ":" . $maxy ."]\n"; - print PIPE "set style data points\n"; + print PIPE "set style data $style\n"; print PIPE "set grid\n"; for(my $i=0; $i<$numberOfStreams; $i++) { From 44c2d22c592eecbe512f83d52cdb0e688271fdaa Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 9 Feb 2009 03:17:26 -0800 Subject: [PATCH 006/270] rehauled drivegnuplot, support all-at-once plotting as a cmdline option Ignore-this: 77ef24b11e28017f77c9a2015701d73c darcs-hash:20090209111726-0cb85-ac339192253c86d402a4486152ee3f9babcf5bcf.gz --- driveGnuPlots.pl | 95 ++++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 677c35e..bae1f8e 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -1,10 +1,15 @@ #!/usr/bin/perl -w use strict; use Getopt::Long; +use Data::Dumper; +# stream in the data by default # point plotting by default -my %options = ( "lines" => 0); +my %options = ( "stream" => 1, + "lines" => 0); + GetOptions(\%options, + "stream!", "lines!"); # set up plotting style @@ -32,14 +37,6 @@ sub Arg { $ARGV[int($_[0])]; } -sub plotHeader -{ - my ($xcounter, $samples, $numberOfStreams, $pipe) = @_; - #print "stream $streamIdx: "; - print $pipe "set xrange [".($xcounter-$samples).":".($xcounter+1)."]\n"; - print $pipe 'plot ' . join(', ' , ('"-" notitle') x $numberOfStreams) . "\n"; -} - sub main { my $argIdx = 0; my $numberOfStreams = Arg($argIdx++); @@ -69,44 +66,64 @@ sub main { print PIPE "set grid\n"; for(my $i=0; $i<$numberOfStreams; $i++) { - my @data = []; - push @buffers, @data; + push @buffers, []; } my $streamIdx = 0; select((select(STDOUT), $| = 1)[0]); - my $xcounter = 0; - while(<>) { - chomp; - my $line = $_; - plotHeader($xcounter, $samples, $numberOfStreams, *PIPE) if($streamIdx == 0); - foreach my $point ($line =~ /([-]?[0-9\.]+)/g) - { - my $buf = $buffers[$streamIdx]; + my $xlast = 0; + while(<>) + { + chomp; + my $line = $_; + foreach my $point ($line =~ /([-]?[0-9\.]+)/g) { + my $buf = $buffers[$streamIdx]; - # data buffering (up to stream sample size) - push @{$buf}, $point; + # data buffering (up to stream sample size) + push @{$buf}, $point; + shift @{$buf} if(@{$buf} > $samples && $options{"stream"}); - my $cnt = 0; - for my $elem (reverse @{$buf}) { - #print " ".$elem; - print PIPE ($xcounter-$cnt)." ".$elem."\n"; - $cnt++; - } - #print "\n"; - print PIPE "e\n"; - if ($cnt>=$samples) { - shift @{$buf}; - } - $streamIdx++; - if ($streamIdx == $numberOfStreams) { - $streamIdx = 0; - $xcounter++; - } + $streamIdx++; + if ($streamIdx == $numberOfStreams) { + $streamIdx = 0; + plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers) if($options{"stream"}); + $xlast++; } + } } - print PIPE "exit;\n"; - close PIPE; + + if($options{"stream"}) + { + print PIPE "exit;\n"; + close PIPE; + } + else + { + $samples = @{$buffers[0]}; + plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers); + } + sleep 100000; } +sub plotStoredData +{ + my ($xlast, $samples, $numberOfStreams, $pipe, $buffers) = @_; + + my $x0 = $xlast - $samples + 1; + print $pipe "set xrange [$x0:$xlast]\n"; + print $pipe 'plot ' . join(', ' , ('"-" notitle') x $numberOfStreams) . "\n"; + + foreach my $buf (@{$buffers}) + { + # 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"; + } +} + + main; From d03c5624ce92b1f390fbabc4bb5d8feb414fac1b Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 6 Mar 2009 13:46:32 -0800 Subject: [PATCH 007/270] driveGnuPlots: more complete usage message Ignore-this: e0821e2a1c464718be811a958d1f11ba darcs-hash:20090306214632-0cb85-ecd795be11554b1669f23ef2e72bf21e35ee0297.gz --- driveGnuPlots.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index bae1f8e..d786692 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -25,6 +25,9 @@ where mandatory options are (in order): Stream_WindowSampleSize this many samples Stream_YRangeMin Stream_YRangeMax Min and Max y values +also + --[no]stream Do [not] display the data a point at a time, as it comes in + --[no]lines Do [not] draw lines to connect consecutive points OEF exit(1); } From d61b9bc2ffede6b8f92124bb856f2e948e17f0ab Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 4 Aug 2009 10:37:13 -0700 Subject: [PATCH 008/270] gnuplot drive now has options for labels Ignore-this: cd66572ad6410084fe5928187edab99 darcs-hash:20090804173713-0cb85-df03115d7fb93fac9532c3180b740eaec8e1a6ea.gz --- driveGnuPlots.pl | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index d786692..6c20eeb 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -10,7 +10,11 @@ my %options = ( "stream" => 1, GetOptions(\%options, "stream!", - "lines!"); + "lines!", + "legend:s@", + "xlabel:s", + "ylabel:s", + "title:s"); # set up plotting style my $style = "points"; @@ -26,8 +30,12 @@ where mandatory options are (in order): Stream_YRangeMin Stream_YRangeMax Min and Max y values also - --[no]stream Do [not] display the data a point at a time, as it comes in - --[no]lines Do [not] draw lines to connect consecutive points + --[no]stream Do [not] display the data a point at a time, as it comes in + --[no]lines Do [not] draw lines to connect consecutive points + --xlabel xxx Set x-axis label + --ylabel xxx Set y-axis label + --title xxx Set the title of the plot + --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves OEF exit(1); } @@ -68,6 +76,16 @@ sub main { print PIPE "set style data $style\n"; print PIPE "set grid\n"; + print(PIPE "set xlabel \"" . $options{"xlabel"} . "\"\n") if $options{"xlabel"}; + print(PIPE "set ylabel \"" . $options{"ylabel"} . "\"\n") if $options{"ylabel"}; + print(PIPE "set title \"" . $options{"title" } . "\"\n") if $options{"title"}; + + my @legend; +# for the specified values, set the legend entries to 'legend "title 1"', etc + @legend = map({"title \"$_\""} @{$options{"legend"}}) if($options{"legend"}); +# now append "notitle" to all the non-specified legend entries + push @legend, ("notitle") x ($numberOfStreams - @legend); + for(my $i=0; $i<$numberOfStreams; $i++) { push @buffers, []; } @@ -89,7 +107,7 @@ sub main { $streamIdx++; if ($streamIdx == $numberOfStreams) { $streamIdx = 0; - plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers) if($options{"stream"}); + plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@legend) if($options{"stream"}); $xlast++; } } @@ -103,18 +121,18 @@ sub main { else { $samples = @{$buffers[0]}; - plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers); + plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@legend); } sleep 100000; } sub plotStoredData { - my ($xlast, $samples, $numberOfStreams, $pipe, $buffers) = @_; + my ($xlast, $samples, $numberOfStreams, $pipe, $buffers, $legend) = @_; my $x0 = $xlast - $samples + 1; print $pipe "set xrange [$x0:$xlast]\n"; - print $pipe 'plot ' . join(', ' , ('"-" notitle') x $numberOfStreams) . "\n"; + print $pipe 'plot ' . join(', ' , map({ "\"-\" $_"} @$legend) ) . "\n"; foreach my $buf (@{$buffers}) { From 041bdad232ecbf90694b863de49c566d11b9db24 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 4 Aug 2009 13:50:10 -0700 Subject: [PATCH 009/270] gnuplot supports plots on the y2 axis Ignore-this: a18a086b3edf54e33749d3b73243c829 darcs-hash:20090804205010-0cb85-db350da2ced0dd006a7326472bb748e16cbbd658.gz --- driveGnuPlots.pl | 56 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 6c20eeb..e0f11ba 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -11,10 +11,14 @@ my %options = ( "stream" => 1, GetOptions(\%options, "stream!", "lines!", - "legend:s@", - "xlabel:s", - "ylabel:s", - "title:s"); + "legend=s@", + "xlabel=s", + "ylabel=s", + "y2label=s", + "title=s", + "y2min=f", + "y2max=f", + "y2=i@"); # set up plotting style my $style = "points"; @@ -34,21 +38,32 @@ also --[no]lines Do [not] draw lines to connect consecutive points --xlabel xxx Set x-axis label --ylabel xxx Set y-axis label + --y2label xxx Set y2-axis label --title xxx Set the title of the plot --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves + --y2min xxx Set the range for the y2 axis. Both or neither of these have to be specified + --y2max xxx Set the range for the y2 axis. Both or neither of these have to be specified + --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed OEF - exit(1); } sub Arg { if ($#ARGV < $_[0]) { print "Expected parameter missing...\n\n"; usage; + die("Error parsing args\n"); } $ARGV[int($_[0])]; } sub main { + if( defined $options{"y2min"} && !defined $options{"y2max"} || + !defined $options{"y2min"} && defined $options{"y2max"} ) + { + usage; + die("Both or neither of y2min,y2max should be specified\n"); + } + my $argIdx = 0; my $numberOfStreams = Arg($argIdx++); print "Will display $numberOfStreams Streams...\n"; @@ -72,20 +87,27 @@ sub main { select((select(PIPE), $| = 1)[0]); print PIPE "set xtics\n"; print PIPE "set ytics\n"; + print PIPE "set y2tics\n"; print PIPE "set yrange [". $miny . ":" . $maxy ."]\n"; + print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if $options{"y2max"}; print PIPE "set style data $style\n"; print PIPE "set grid\n"; - print(PIPE "set xlabel \"" . $options{"xlabel"} . "\"\n") if $options{"xlabel"}; - print(PIPE "set ylabel \"" . $options{"ylabel"} . "\"\n") if $options{"ylabel"}; - print(PIPE "set title \"" . $options{"title" } . "\"\n") if $options{"title"}; + print(PIPE "set xlabel \"" . $options{"xlabel" } . "\"\n") if $options{"xlabel"}; + print(PIPE "set ylabel \"" . $options{"ylabel" } . "\"\n") if $options{"ylabel"}; + print(PIPE "set y2label \"" . $options{"y2label"} . "\"\n") if $options{"y2label"}; + print(PIPE "set title \"" . $options{"title" } . "\"\n") if $options{"title"}; - my @legend; -# for the specified values, set the legend entries to 'legend "title 1"', etc - @legend = map({"title \"$_\""} @{$options{"legend"}}) if($options{"legend"}); -# now append "notitle" to all the non-specified legend entries - push @legend, ("notitle") x ($numberOfStreams - @legend); +# For the specified values, set the legend entries to 'title "blah +# blah"'. Otherwise, "notitle". + my @extraopts; + @extraopts = map({"title \"$_\""} @{$options{"legend"}}) if($options{"legend"}); + push @extraopts, ("notitle") x ($numberOfStreams - @extraopts); +# For the values requested to be printed on the y2 axis, set that + foreach my $y2idx (@{$options{"y2"}}) { $extraopts[$y2idx] .= " axes x1y2"; } + +# This is ugly, but "([]) x $numberOfStreams" was giving me references into a single physical list for(my $i=0; $i<$numberOfStreams; $i++) { push @buffers, []; } @@ -107,7 +129,7 @@ sub main { $streamIdx++; if ($streamIdx == $numberOfStreams) { $streamIdx = 0; - plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@legend) if($options{"stream"}); + plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@extraopts) if($options{"stream"}); $xlast++; } } @@ -121,18 +143,18 @@ sub main { else { $samples = @{$buffers[0]}; - plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@legend); + plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@extraopts); } sleep 100000; } sub plotStoredData { - my ($xlast, $samples, $numberOfStreams, $pipe, $buffers, $legend) = @_; + my ($xlast, $samples, $numberOfStreams, $pipe, $buffers, $extraopts) = @_; my $x0 = $xlast - $samples + 1; print $pipe "set xrange [$x0:$xlast]\n"; - print $pipe 'plot ' . join(', ' , map({ "\"-\" $_"} @$legend) ) . "\n"; + print $pipe 'plot ' . join(', ' , map({ "\"-\" $_"} @$extraopts) ) . "\n"; foreach my $buf (@{$buffers}) { From c77a8c0a4315a035436ca59b0b2cef0b1f210e7f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 4 Aug 2009 13:57:17 -0700 Subject: [PATCH 010/270] allow line-only plots Ignore-this: 59483d197ae73a0c307ca726d2d96dc3 darcs-hash:20090804205717-0cb85-998aa3e993c9063debbf5235c0d059419b695101.gz --- driveGnuPlots.pl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index e0f11ba..d382872 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -6,8 +6,8 @@ use Data::Dumper; # stream in the data by default # point plotting by default my %options = ( "stream" => 1, - "lines" => 0); - + "points" => 0, + "lines" => 0,); GetOptions(\%options, "stream!", "lines!", @@ -21,8 +21,11 @@ GetOptions(\%options, "y2=i@"); # set up plotting style -my $style = "points"; -$style = "linespoints" if($options{"lines"}); +my $style = ""; +if($options{"lines"}) { $style .= "lines";} +if($options{"points"}) { $style .= "points";} + +if(!$style) { $style = "points"; } sub usage { print "Usage: $0 \n"; From dec8b6cac6f27a44258136840d37087f338c17d4 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 4 Aug 2009 14:36:11 -0700 Subject: [PATCH 011/270] thicker lines for y2 plots Ignore-this: 5b2e5aabe42c4324fd60de747874cefd darcs-hash:20090804213611-0cb85-fdbb83b21fbf16161ee5392a1add972982868fbe.gz --- driveGnuPlots.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index d382872..e8bbfd3 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -108,7 +108,7 @@ sub main { push @extraopts, ("notitle") x ($numberOfStreams - @extraopts); # For the values requested to be printed on the y2 axis, set that - foreach my $y2idx (@{$options{"y2"}}) { $extraopts[$y2idx] .= " axes x1y2"; } + foreach my $y2idx (@{$options{"y2"}}) { $extraopts[$y2idx] .= " axes x1y2 linewidth 3"; } # This is ugly, but "([]) x $numberOfStreams" was giving me references into a single physical list for(my $i=0; $i<$numberOfStreams; $i++) { From a8bb73ec90ce1f88055a007dac22fb0b2c51e3e8 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 4 Aug 2009 16:03:57 -0700 Subject: [PATCH 012/270] driveGnuplot can make hardcopies Ignore-this: 977b3fbc29030371c121450c8095f7ef darcs-hash:20090804230357-0cb85-2fb14bffc9b4f35a82e03a89c4b465b35f93e7d7.gz --- driveGnuPlots.pl | 53 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index e8bbfd3..5ed761d 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -1,6 +1,7 @@ #!/usr/bin/perl -w use strict; use Getopt::Long; +use Time::HiRes qw( usleep ); use Data::Dumper; # stream in the data by default @@ -18,7 +19,8 @@ GetOptions(\%options, "title=s", "y2min=f", "y2max=f", - "y2=i@"); + "y2=i@", + "hardcopy=s"); # set up plotting style my $style = ""; @@ -47,6 +49,7 @@ also --y2min xxx Set the range for the y2 axis. Both or neither of these have to be specified --y2max xxx Set the range for the y2 axis. Both or neither of these have to be specified --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed + --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename OEF } @@ -66,6 +69,10 @@ sub main { usage; die("Both or neither of y2min,y2max should be specified\n"); } + if( defined $options{"hardcopy"} && $options{"stream"} ) + { + die("If making a hardcopy, we shouldn't be streaming. Doing nothing\n"); + } my $argIdx = 0; my $numberOfStreams = Arg($argIdx++); @@ -88,6 +95,30 @@ sub main { open PIPE, "|gnuplot" || die "Can't initialize gnuplot\n"; select((select(PIPE), $| = 1)[0]); + my $temphardcopyfile; + my $outputfile; + my $outputfileType; + if( defined $options{"hardcopy"}) + { + $outputfile = $options{"hardcopy"}; + ($outputfileType) = $outputfile =~ /\.(ps|pdf|png)$/; + if(!$outputfileType) { die("Only .ps, .pdf and .png supported\n"); } + + if ($outputfileType eq "png") + { + print PIPE "set terminal png\n"; + } + else + { + print PIPE "set terminal postscript solid color landscape 10\n"; + } +# write to a temporary file first + $temphardcopyfile = $outputfile; + $temphardcopyfile =~ s{/}{_}g; + $temphardcopyfile = "/tmp/$temphardcopyfile"; + print PIPE "set output \"$temphardcopyfile\"\n"; + } + print PIPE "set xtics\n"; print PIPE "set ytics\n"; print PIPE "set y2tics\n"; @@ -147,6 +178,26 @@ sub main { { $samples = @{$buffers[0]}; plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@extraopts); + + 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; } From 37667ddec347b051c64d9826f00f60da0d0ad5b7 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Aug 2009 11:59:38 -0700 Subject: [PATCH 013/270] gnuplot driver can parse scientific notation Ignore-this: 9c3fa6a5d1974f806ff6cd587c3af5b5 darcs-hash:20090806185938-0cb85-0d54fd39632f145019e923dc9123bc297bbf37fd.gz --- driveGnuPlots.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 5ed761d..4d50e63 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -149,11 +149,14 @@ sub main { my $streamIdx = 0; select((select(STDOUT), $| = 1)[0]); my $xlast = 0; + + # regexp for a possibly floating point, possibly scientific notation number + my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/; while(<>) { chomp; my $line = $_; - foreach my $point ($line =~ /([-]?[0-9\.]+)/g) { + foreach my $point ($line =~ /$numRE/g) { my $buf = $buffers[$streamIdx]; # data buffering (up to stream sample size) From 144a2f1a01f5c122cebd9bd90940542d353027e6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Aug 2009 12:09:46 -0700 Subject: [PATCH 014/270] no ytics on the y2 axis Ignore-this: dc7f313671e10d17c1fe8a3a37e00ef9 darcs-hash:20090806190946-0cb85-d196a97f2c7801aa6ffc6c9a1b0adcd59f372928.gz --- driveGnuPlots.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 4d50e63..2e8b6db 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -120,7 +120,7 @@ sub main { } print PIPE "set xtics\n"; - print PIPE "set ytics\n"; + print PIPE "set ytics nomirror\n"; print PIPE "set y2tics\n"; print PIPE "set yrange [". $miny . ":" . $maxy ."]\n"; print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if $options{"y2max"}; From 2d55fa6f300ae2db04f0a9925f03ee599cff96a5 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 10 Aug 2009 11:14:16 -0700 Subject: [PATCH 015/270] y-range specified with options instead of hard-coded cmdline positions Ignore-this: 956b97272172f6adbe785cb62fd6ad0a darcs-hash:20090810181416-0cb85-eb9e872523d96a51e33c174a995df684659cdd8a.gz --- driveGnuPlots.pl | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 2e8b6db..b2c7807 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -36,7 +36,6 @@ where mandatory options are (in order): NumberOfStreams How many streams to plot Stream_WindowSampleSize this many samples - Stream_YRangeMin Stream_YRangeMax Min and Max y values also --[no]stream Do [not] display the data a point at a time, as it comes in @@ -46,6 +45,8 @@ also --y2label xxx Set y2-axis label --title xxx Set the title of the plot --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves + --ymin xxx Set the range for the y axis. Both or neither of these have to be specified + --ymax xxx Set the range for the y axis. Both or neither of these have to be specified --y2min xxx Set the range for the y2 axis. Both or neither of these have to be specified --y2max xxx Set the range for the y2 axis. Both or neither of these have to be specified --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed @@ -63,6 +64,12 @@ sub Arg { } sub main { + if( defined $options{"ymin"} && !defined $options{"ymax"} || + !defined $options{"ymin"} && defined $options{"ymax"} ) + { + usage; + die("Both or neither of ymin,ymax should be specified\n"); + } if( defined $options{"y2min"} && !defined $options{"y2max"} || !defined $options{"y2min"} && defined $options{"y2max"} ) { @@ -81,15 +88,9 @@ sub main { my $samples = Arg($argIdx++); print "Will use a window of $samples samples\n"; - my $miny = Arg($argIdx++); - my $maxy = Arg($argIdx++); - print "Will use a range of [$miny, $maxy]\n"; - my @buffers; shift @ARGV; # number of streams shift @ARGV; # sample size - shift @ARGV; # miny - shift @ARGV; # maxy local *PIPE; open PIPE, "|gnuplot" || die "Can't initialize gnuplot\n"; @@ -122,7 +123,7 @@ sub main { print PIPE "set xtics\n"; print PIPE "set ytics nomirror\n"; print PIPE "set y2tics\n"; - print PIPE "set yrange [". $miny . ":" . $maxy ."]\n"; + print PIPE "set yrange [". $options{"ymin"} . ":" . $options{"ymax"} ."]\n" if $options{"y2max"}; print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if $options{"y2max"}; print PIPE "set style data $style\n"; print PIPE "set grid\n"; From 514203f76c47155f6250021e57cefd35996c4bad Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 10 Aug 2009 12:42:48 -0700 Subject: [PATCH 016/270] forgot to add GetOpt options for the y extents Ignore-this: 138384ef08603a6d473975dbc697806e darcs-hash:20090810194248-0cb85-5bbcc14d6464b27c6b794883212ea7841d97a1e5.gz --- driveGnuPlots.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index b2c7807..9d5b90e 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -17,6 +17,8 @@ GetOptions(\%options, "ylabel=s", "y2label=s", "title=s", + "ymin=f", + "ymax=f", "y2min=f", "y2max=f", "y2=i@", From de3a72fd36d222546395b11392628bb9753bc905 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 10 Aug 2009 12:54:21 -0700 Subject: [PATCH 017/270] forgot "points" in the GetOpt list Ignore-this: 5cbfb04372e86b2bc9d557d743d67976 darcs-hash:20090810195421-0cb85-78da4571d3bcbe6ad5ce78196db5a20f4e1951e8.gz --- driveGnuPlots.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 9d5b90e..4275276 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -12,6 +12,7 @@ my %options = ( "stream" => 1, GetOptions(\%options, "stream!", "lines!", + "points!", "legend=s@", "xlabel=s", "ylabel=s", From 1d33ed48bbb77463617eca21841a4d90083345ed Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 10 Aug 2009 12:57:49 -0700 Subject: [PATCH 018/270] number of streams now dynamically parsed Ignore-this: 6c27c400e38c516d9cddc6d19630916e darcs-hash:20090810195749-0cb85-3b7edfccd8d0175b4f2eba7e24187d3ea9678115.gz --- driveGnuPlots.pl | 163 +++++++++++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 61 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 4275276..a6e4874 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -4,6 +4,12 @@ use Getopt::Long; use Time::HiRes qw( usleep ); use Data::Dumper; +# 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, @@ -18,12 +24,14 @@ GetOptions(\%options, "ylabel=s", "y2label=s", "title=s", + "xlen=i", "ymin=f", "ymax=f", "y2min=f", "y2max=f", "y2=i@", - "hardcopy=s"); + "hardcopy=s", + "help"); # set up plotting style my $style = ""; @@ -35,12 +43,6 @@ if(!$style) { $style = "points"; } sub usage { print "Usage: $0 \n"; print <) { - chomp; - my $line = $_; - foreach my $point ($line =~ /$numRE/g) { - my $buf = $buffers[$streamIdx]; + 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"}); - - $streamIdx++; - if ($streamIdx == $numberOfStreams) { - $streamIdx = 0; - plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@extraopts) if($options{"stream"}); - $xlast++; - } + 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"}) @@ -183,8 +202,8 @@ sub main { } else { - $samples = @{$buffers[0]}; - plotStoredData($xlast, $samples, $numberOfStreams, *PIPE, \@buffers, \@extraopts); + $samples = @{$curves[0]->{"data"}}; + plotStoredData($xlast, $samples, *PIPE); if( defined $options{"hardcopy"}) { @@ -211,17 +230,20 @@ sub main { sub plotStoredData { - my ($xlast, $samples, $numberOfStreams, $pipe, $buffers, $extraopts) = @_; + my ($xlast, $samples, $pipe) = @_; my $x0 = $xlast - $samples + 1; print $pipe "set xrange [$x0:$xlast]\n"; - print $pipe 'plot ' . join(', ' , map({ "\"-\" $_"} @$extraopts) ) . "\n"; - foreach my $buf (@{$buffers}) + 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}) { + my $x = $x0 + $samples - @$buf; + for my $elem (@$buf) { print $pipe "$x $elem\n"; $x++; } @@ -229,5 +251,24 @@ sub plotStoredData } } +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; From 7a3ca33118ff0202cecab788bd6a3454a2124b12 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 10 Aug 2009 13:04:39 -0700 Subject: [PATCH 019/270] y extents are optional Ignore-this: 809894afece147f868685c0bbeaac9f5 darcs-hash:20090810200439-0cb85-a14ece790280871a4ff71949502d1c9ae0548232.gz --- driveGnuPlots.pl | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index a6e4874..f26353d 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -14,7 +14,11 @@ my @curves = (); # point plotting by default my %options = ( "stream" => 1, "points" => 0, - "lines" => 0,); + "lines" => 0, + "ymin" => "", + "ymax" => "", + "y2min" => "", + "y2max" => ""); GetOptions(\%options, "stream!", "lines!", @@ -66,18 +70,6 @@ sub main { usage; return; } - if( defined $options{"ymin"} && !defined $options{"ymax"} || - !defined $options{"ymin"} && defined $options{"ymax"} ) - { - usage; - die("Both or neither of ymin,ymax should be specified\n"); - } - if( defined $options{"y2min"} && !defined $options{"y2max"} || - !defined $options{"y2min"} && defined $options{"y2max"} ) - { - usage; - die("Both or neither of y2min,y2max should be specified\n"); - } if( defined $options{"hardcopy"} && $options{"stream"} ) { usage; From bcea7fb24b04edc1c6735a198ced5be13526e036 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 11 Aug 2009 00:09:12 -0700 Subject: [PATCH 020/270] autoflush in a more sane way Ignore-this: 8fc465e6dc0e7cb69d263897dbb36a48 darcs-hash:20090811070912-0cb85-2d06faa276311483cb21f8ed965f59ea486f215f.gz --- driveGnuPlots.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index f26353d..7efc365 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -2,6 +2,7 @@ use strict; use Getopt::Long; use Time::HiRes qw( usleep ); +use IO::Handle; use Data::Dumper; # list containing the plot data. Each element is a hash describing the extra @@ -84,7 +85,7 @@ sub main { local *PIPE; open PIPE, "|gnuplot" || die "Can't initialize gnuplot\n"; - select((select(PIPE), $| = 1)[0]); + autoflush PIPE 1; my $temphardcopyfile; my $outputfile; From 43711c90f92b1d89b45974826e7bf6911d0cd018 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 11 Aug 2009 00:30:25 -0700 Subject: [PATCH 021/270] STDOUT now sensibly autoflushing also Ignore-this: 6dcd91878412e54d72fa3180cf437cc5 darcs-hash:20090811073025-0cb85-b6b9de7ca32ba0574fcabaf63490a1c3e77c8135.gz --- driveGnuPlots.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 7efc365..4038abf 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -5,6 +5,8 @@ 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 @@ -144,7 +146,6 @@ sub main { } } - select((select(STDOUT), $| = 1)[0]); my $xlast = 0; # regexp for a possibly floating point, possibly scientific notation number From 78b6147d864b9632354ed74aa0235122b9a1047b Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 11 Aug 2009 01:54:38 -0700 Subject: [PATCH 022/270] gnuplot driver can now use the x coord Ignore-this: 319d354c62ed4d1dbc2da0f77a712356 darcs-hash:20090811085438-0cb85-c3852704104f38d56708cf25d442edec38c3174c.gz --- driveGnuPlots.pl | 88 +++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 4038abf..d9af68a 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -83,7 +83,7 @@ sub main { usage; die("Must specify the size of the moving x-window. Doing nothing\n"); } - my $samples = $options{"xlen"}; + my $xwindow = $options{"xlen"}; local *PIPE; open PIPE, "|gnuplot" || die "Can't initialize gnuplot\n"; @@ -146,47 +146,35 @@ sub main { } } - my $xlast = 0; - # regexp for a possibly floating point, possibly scientific notation number my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/; while(<>) { - foreach my $curve (@curves) + # parse the incoming data lines. The format is + # x idx0 dat0 idx1 dat1 .... + # where idxX is the index of the curve that datX corresponds to + /($numRE)/gc or next; + my $x = $1; + + while(/([0-9]+) ($numRE)/gc) { - my $buf = $curve->{"data"}; + my $idx = $1; + my $point = $2; - # get the next datapoint, if there is one - my $point; - if(/($numRE)/gc) + # if this curve index doesn't exist, create curve up-to this index + while(!exists $curves[$idx]) { - $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; + newCurve("", ""); } - # data buffering (up to stream sample size) - push @$buf, $point; - shift @$buf if(@$buf > $samples && $options{"stream"}); + push @{$curves[$idx]->{"data"}}, [$x, $point]; } - # if any extra data is available, create new curves for it - while(/($numRE)/gc) + if($options{"stream"}) { - newCurve("", "", $1); + cutOld($x - $xwindow); + plotStoredData($x - $xwindow, $x); } - - plotStoredData($xlast, $samples, *PIPE) if($options{"stream"}); - $xlast++; } if($options{"stream"}) @@ -196,8 +184,7 @@ sub main { } else { - $samples = @{$curves[0]->{"data"}}; - plotStoredData($xlast, $samples, *PIPE); + plotStoredData(); if( defined $options{"hardcopy"}) { @@ -222,24 +209,33 @@ sub main { sleep 100000; } +sub cutOld +{ + my ($oldestx) = @_; + foreach (@curves) + { + my $xy = $_->{"data"}; + while(@$xy && $xy->[0][0] < $oldestx) + { + shift @$xy; + } + } +} + sub plotStoredData { - my ($xlast, $samples, $pipe) = @_; - - my $x0 = $xlast - $samples + 1; - print $pipe "set xrange [$x0:$xlast]\n"; + my ($xmin, $xmax) = @_; + print PIPE "set xrange [$xmin:$xmax]\n" if defined $xmin; my @extraopts = map {$_->{"extraopts"}} @curves; - print $pipe 'plot ' . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; + 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++; + my ($x, $y) = @$elem; + print PIPE "$x $y\n"; } print PIPE "e\n"; } @@ -251,18 +247,10 @@ sub newCurve() 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] - } + $newpoint = [] unless defined $newpoint; push ( @curves, {"extraopts" => " $opts", - "data" => $data} ); + "data" => $newpoint} ); } main; From 0dab1a0ec0776ffd768baeba9f0f4c4087f9d07d Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 11 Aug 2009 11:18:52 -0700 Subject: [PATCH 023/270] gnuplot driver more efficient. while,shift -> firstidx,splice Ignore-this: 78741ffed855a5122e14486000af4154 darcs-hash:20090811181852-0cb85-ca6a28ee8151f7c8671c0d69dce8f29ed481fe4f.gz --- driveGnuPlots.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index d9af68a..9baab66 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -3,6 +3,7 @@ use strict; use Getopt::Long; use Time::HiRes qw( usleep ); use IO::Handle; +use List::MoreUtils qw( first_index ); use Data::Dumper; autoflush STDOUT 1; @@ -215,9 +216,11 @@ sub cutOld foreach (@curves) { my $xy = $_->{"data"}; - while(@$xy && $xy->[0][0] < $oldestx) + + if( @$xy ) { - shift @$xy; + my $firstInWindow = first_index {$_->[0] >= $oldestx} @$xy; + splice( @$xy, 0, $firstInWindow ) unless $firstInWindow == -1; } } } From 13d6528473716f0f6fab707904008d2fda04902b Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 11 Aug 2009 14:11:24 -0700 Subject: [PATCH 024/270] don't try to plot empty curves Ignore-this: 8595770256deec271d0a7715a0e1ed14 darcs-hash:20090811211124-0cb85-8e26b73e0bb0071e246d2fe80512203c1152ac1f.gz --- driveGnuPlots.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 9baab66..f48d318 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -230,12 +230,13 @@ sub plotStoredData my ($xmin, $xmax) = @_; print PIPE "set xrange [$xmin:$xmax]\n" if defined $xmin; - my @extraopts = map {$_->{"extraopts"}} @curves; + my @extraopts = map {$_->{"extraopts"}} grep {@{$_->{"data"}}} @curves; print PIPE 'plot ' . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; foreach my $curve (@curves) { my $buf = $curve->{"data"}; + next unless @$buf; for my $elem (@$buf) { my ($x, $y) = @$elem; print PIPE "$x $y\n"; From 07a13f7977929feb86d699b8775d0b7ffa779d5e Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 24 Aug 2009 14:31:42 -0700 Subject: [PATCH 025/270] gnuplot driver limited to replotting at 1fps Ignore-this: 2ce7b4bcffd97e593b34693ddab54147 darcs-hash:20090824213142-0cb85-3301d931b63db020724e83e3bd14b3b58d99a712.gz --- driveGnuPlots.pl | 146 +++++++++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 55 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index f48d318..918436c 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -1,10 +1,12 @@ #!/usr/bin/perl -w use strict; use Getopt::Long; -use Time::HiRes qw( usleep ); +use Time::HiRes qw( usleep gettimeofday tv_interval); use IO::Handle; use List::MoreUtils qw( first_index ); use Data::Dumper; +use threads; +use Thread::Queue; autoflush STDOUT 1; @@ -48,44 +50,55 @@ if($options{"points"}) { $style .= "points";} if(!$style) { $style = "points"; } -sub usage { - print "Usage: $0 \n"; - print <new(); +my $addThr = threads->create(\&mainThread); +my $plotThr = threads->create(\&plotThread); + +while(<>) +{ + $dataQueue->enqueue($_); } -sub main { - if( defined $options{"help"} ) - { - usage; - return; - } - if( defined $options{"hardcopy"} && $options{"stream"} ) - { - usage; - die("If making a hardcopy, we shouldn't be streaming. Doing nothing\n"); - } - if( !defined $options{"xlen"} ) - { - usage; - die("Must specify the size of the moving x-window. Doing nothing\n"); - } - my $xwindow = $options{"xlen"}; +$dataQueue->enqueue("Plot now"); +$dataQueue->enqueue(undef); +$addThr->join(); +$plotThr->join(); + + + + +sub plotThread +{ + while(1) + { + sleep(1); + $dataQueue->enqueue("Plot now"); + } +} + +sub mainThread { local *PIPE; open PIPE, "|gnuplot" || die "Can't initialize gnuplot\n"; autoflush PIPE 1; @@ -149,32 +162,36 @@ sub main { # regexp for a possibly floating point, possibly scientific notation number my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/; - while(<>) + my $xlast; + while( $_ = $dataQueue->dequeue() ) { - # parse the incoming data lines. The format is - # x idx0 dat0 idx1 dat1 .... - # where idxX is the index of the curve that datX corresponds to - /($numRE)/gc or next; - my $x = $1; - - while(/([0-9]+) ($numRE)/gc) + if(!/Plot now/) { - my $idx = $1; - my $point = $2; + # parse the incoming data lines. The format is + # x idx0 dat0 idx1 dat1 .... + # where idxX is the index of the curve that datX corresponds to + /($numRE)/gc or next; + $xlast = $1; - # if this curve index doesn't exist, create curve up-to this index - while(!exists $curves[$idx]) + while(/([0-9]+) ($numRE)/gc) { - newCurve("", ""); - } + my $idx = $1; + my $point = $2; - push @{$curves[$idx]->{"data"}}, [$x, $point]; + # if this curve index doesn't exist, create curve up-to this index + while(!exists $curves[$idx]) + { + newCurve("", ""); + } + + push @{$curves[$idx]->{"data"}}, [$xlast, $point]; + } } - if($options{"stream"}) + elsif($options{"stream"}) { - cutOld($x - $xwindow); - plotStoredData($x - $xwindow, $x); + cutOld($xlast - $xwindow); + plotStoredData($xlast - $xwindow, $xlast); } } @@ -257,4 +274,23 @@ sub newCurve() "data" => $newpoint} ); } -main; +sub usage { + print "Usage: $0 \n"; + print < Date: Thu, 27 Aug 2009 10:08:49 -0700 Subject: [PATCH 026/270] don't bother with the plot thread if we're not streaming Ignore-this: d748c070654b61db45e27490428df154 darcs-hash:20090827170849-0cb85-e6e0499441f19560a8f6fbf10fadd5060f659a03.gz --- driveGnuPlots.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 918436c..a9c243d 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -73,7 +73,7 @@ my $xwindow = $options{"xlen"}; # now start the data acquisition and plotting threads my $dataQueue = Thread::Queue->new(); my $addThr = threads->create(\&mainThread); -my $plotThr = threads->create(\&plotThread); +my $plotThr = threads->create(\&plotThread) if(!$options{"stream"}); while(<>) { @@ -84,7 +84,7 @@ $dataQueue->enqueue("Plot now"); $dataQueue->enqueue(undef); $addThr->join(); -$plotThr->join(); +$plotThr->join() if(!$options{"stream"}); From ff0404838271306075289a9c5b9b8a18e3db642f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 27 Aug 2009 10:30:55 -0700 Subject: [PATCH 027/270] better handling of streaming and non-streaming plotting Ignore-this: f7cbc85b0382a4810db13d01e65f4bd5 darcs-hash:20090827173055-0cb85-aec6122e4405eb8a1f9d5bd61bf683c47837cba0.gz --- driveGnuPlots.pl | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index a9c243d..0284e2f 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -72,20 +72,33 @@ my $xwindow = $options{"xlen"}; # now start the data acquisition and plotting threads my $dataQueue = Thread::Queue->new(); -my $addThr = threads->create(\&mainThread); -my $plotThr = threads->create(\&plotThread) if(!$options{"stream"}); -while(<>) + +if($options{"stream"}) { - $dataQueue->enqueue($_); + my $addThr = threads->create(\&mainThread); + my $plotThr = threads->create(\&plotThread); + + while(<>) + { + $dataQueue->enqueue($_); + } + + $dataQueue->enqueue("Plot now"); + $dataQueue->enqueue(undef); + + $addThr->join(); + $plotThr->join(); +} +else +{ + while(<>) + { + $dataQueue->enqueue($_); + } + $dataQueue->enqueue(undef); + mainThread(); } - -$dataQueue->enqueue("Plot now"); -$dataQueue->enqueue(undef); - -$addThr->join(); -$plotThr->join() if(!$options{"stream"}); - @@ -100,7 +113,7 @@ sub plotThread sub mainThread { local *PIPE; - open PIPE, "|gnuplot" || die "Can't initialize gnuplot\n"; + open PIPE, "|gnuplot --persist" || die "Can't initialize gnuplot\n"; autoflush PIPE 1; my $temphardcopyfile; @@ -195,6 +208,7 @@ sub mainThread { } } + # read in all of the data if($options{"stream"}) { print PIPE "exit;\n"; @@ -224,7 +238,6 @@ sub mainThread { return; } } - sleep 100000; } sub cutOld From d7fd9db35634b8037c4ce519707ec56cca646887 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 27 Aug 2009 13:23:08 -0700 Subject: [PATCH 028/270] persistence for nostream Ignore-this: 8d8ed631ca050aa138ec640db05a84ef darcs-hash:20090827202308-0cb85-76575e918f2b3d47023c155ee2b2dea89d1526de.gz --- driveGnuPlots.pl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 0284e2f..dd7b827 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -113,7 +113,10 @@ sub plotThread sub mainThread { local *PIPE; - open PIPE, "|gnuplot --persist" || die "Can't initialize gnuplot\n"; + my $dopersist = ""; + $dopersist = "--persist" if(!$options{"stream"}); + + open PIPE, "|gnuplot $dopersist" || die "Can't initialize gnuplot\n"; autoflush PIPE 1; my $temphardcopyfile; @@ -237,6 +240,11 @@ sub mainThread { printf "Wrote output to $outputfile\n"; return; } + + # we persist gnuplot, so we shouldn't need this sleep. However, once + # gnuplot exist, but the persistent window sticks around, you can no + # longer interactively zoom the plot. So we still sleep + sleep(100000); } } From 5bf6539a9aab8763c601521601e6f3e47ac0cd34 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 27 Aug 2009 13:32:23 -0700 Subject: [PATCH 029/270] don't try to plot if we have no data Ignore-this: 808c5f30dd3fabc33d6980dce972794 darcs-hash:20090827203223-0cb85-2e0d29077c97f12711a1899f0ae9086860a56da4.gz --- driveGnuPlots.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index dd7b827..8146303 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -204,7 +204,7 @@ sub mainThread { } } - elsif($options{"stream"}) + elsif($options{"stream"} && defined $xlast) { cutOld($xlast - $xwindow); plotStoredData($xlast - $xwindow, $xlast); From c3f314cf9e0eaecd1ec13883be828f4db4635634 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 2 Sep 2009 12:27:45 -0700 Subject: [PATCH 030/270] don't stream if we're making a hardcopy Ignore-this: a9e258fa2c0e80219170f5e11970bc75 darcs-hash:20090902192745-0cb85-5962b13536b4f78da9080c2084b1715a6db86ab8.gz --- driveGnuPlots.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 8146303..c90ba88 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -57,8 +57,7 @@ if( defined $options{"help"} ) } if( defined $options{"hardcopy"} && $options{"stream"} ) { - usage(); - die("If making a hardcopy, we shouldn't be streaming. Doing nothing\n"); + $options{"stream"} = undef; } if( !defined $options{"xlen"} ) { From a66cbbf42475b2f759f52ed3bbc3cab15d86390c Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 8 Sep 2009 11:17:44 -0700 Subject: [PATCH 031/270] no y2 tics if not needed. other script Ignore-this: 7da813657e0093494b2428919c94f393 darcs-hash:20090908181744-0cb85-73f5f460de655559c8d1ef503a20e869d400ec72.gz --- driveGnuPlots.pl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index c90ba88..109ed77 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -143,10 +143,13 @@ sub mainThread { } print PIPE "set xtics\n"; - print PIPE "set ytics nomirror\n"; - print PIPE "set y2tics\n"; + if($options{"y2"}) + { + print PIPE "set ytics nomirror\n"; + print PIPE "set y2tics\n"; + print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if $options{"y2max"}; + } print PIPE "set yrange [". $options{"ymin"} . ":" . $options{"ymax"} ."]\n" if $options{"y2max"}; - print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if $options{"y2max"}; print PIPE "set style data $style\n"; print PIPE "set grid\n"; From ed83f99a6519c57373b6b0d348b11fd8f8a62ea2 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 8 Sep 2009 11:32:22 -0700 Subject: [PATCH 032/270] xlen is floating point. It's not the number of points anymore Ignore-this: bc98aeef65fa61ec7d2dba925150a899 darcs-hash:20090908183222-0cb85-b32209e91a32d3b2da82b7c026ba51095c002d9e.gz --- driveGnuPlots.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 109ed77..16d7cba 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -34,7 +34,7 @@ GetOptions(\%options, "ylabel=s", "y2label=s", "title=s", - "xlen=i", + "xlen=f", "ymin=f", "ymax=f", "y2min=f", From 95a9a1db91463efb6618c63009b52583eb125bfe Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 8 Sep 2009 11:32:44 -0700 Subject: [PATCH 033/270] do not require xlen if !streaming Ignore-this: 41377b9f3e94ad852e88f14e678e30d3 darcs-hash:20090908183244-0cb85-a38c1b999cf6e86ea54eb41573921df9b0875132.gz --- driveGnuPlots.pl | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 16d7cba..4866601 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -55,26 +55,23 @@ if( defined $options{"help"} ) usage(); return; } -if( defined $options{"hardcopy"} && $options{"stream"} ) -{ - $options{"stream"} = undef; -} -if( !defined $options{"xlen"} ) -{ - usage(); - die("Must specify the size of the moving x-window. Doing nothing\n"); -} -my $xwindow = $options{"xlen"}; - - - # now start the data acquisition and plotting threads my $dataQueue = Thread::Queue->new(); - if($options{"stream"}) { + if( defined $options{"hardcopy"}) + { + $options{"stream"} = undef; + } + if( !defined $options{"xlen"} ) + { + usage(); + die("Must specify the size of the moving x-window. Doing nothing\n"); + } + my $xwindow = $options{"xlen"}; + my $addThr = threads->create(\&mainThread); my $plotThr = threads->create(\&plotThread); From 278f0d8fd52b1700b31c65afbae4232740c6e1ac Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 8 Sep 2009 11:35:59 -0700 Subject: [PATCH 034/270] need to declare $xwindow even if not using it Ignore-this: 7770b65e421e705e4661a29d04eaeee9 darcs-hash:20090908183559-0cb85-f5bd8c607bbb61977d06ab6530c2ef8cf07c2593.gz --- driveGnuPlots.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 4866601..592ee7d 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -58,6 +58,7 @@ if( defined $options{"help"} ) # now start the data acquisition and plotting threads my $dataQueue = Thread::Queue->new(); +my $xwindow; if($options{"stream"}) { @@ -70,7 +71,7 @@ if($options{"stream"}) usage(); die("Must specify the size of the moving x-window. Doing nothing\n"); } - my $xwindow = $options{"xlen"}; + $xwindow = $options{"xlen"}; my $addThr = threads->create(\&mainThread); my $plotThr = threads->create(\&plotThread); From 5bf3b09d0cecae4a2495485099109cb139d6b4c1 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 10 Sep 2009 15:11:51 -0700 Subject: [PATCH 035/270] driveGnuPlots.pl speedups. Removed the threadqueue in !streaming, rearranged data Ignore-this: 66c1ef6d9b45a1bd3db49c3696a2b309 darcs-hash:20090910221151-0cb85-becf9bad1e4c07e1c60c8b8c7517d36986076d0f.gz --- driveGnuPlots.pl | 66 +++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 592ee7d..21ef92d 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -10,11 +10,10 @@ use Thread::Queue; 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 = (); +# list containing the plot data. Each element is a reference to a list, +# representing the data for one curve. The first "point" is a string of plot +# options +my @curves = (); # stream in the data by default # point plotting by default @@ -57,7 +56,7 @@ if( defined $options{"help"} ) } # now start the data acquisition and plotting threads -my $dataQueue = Thread::Queue->new(); +my $dataQueue; my $xwindow; if($options{"stream"}) @@ -73,6 +72,7 @@ if($options{"stream"}) } $xwindow = $options{"xlen"}; + $dataQueue = Thread::Queue->new(); my $addThr = threads->create(\&mainThread); my $plotThr = threads->create(\&plotThread); @@ -89,11 +89,6 @@ if($options{"stream"}) } else { - while(<>) - { - $dataQueue->enqueue($_); - } - $dataQueue->enqueue(undef); mainThread(); } @@ -140,6 +135,7 @@ sub mainThread { print PIPE "set output \"$temphardcopyfile\"\n"; } + print PIPE "set terminal x11\n"; print PIPE "set xtics\n"; if($options{"y2"}) { @@ -168,7 +164,7 @@ sub mainThread { my $str = " axes x1y2 linewidth 3"; if(exists $curves[$y2idx]) { - $curves[$y2idx]{"extraopts"} .= $str; + $curves[$y2idx][0] .= $str; } else { @@ -179,17 +175,18 @@ sub mainThread { # regexp for a possibly floating point, possibly scientific notation number my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/; my $xlast; - while( $_ = $dataQueue->dequeue() ) + + while( $_ = ($dataQueue && $dataQueue->dequeue()) || <> ) { - if(!/Plot now/) + if($_ ne "Plot now") { # parse the incoming data lines. The format is # x idx0 dat0 idx1 dat1 .... # where idxX is the index of the curve that datX corresponds to - /($numRE)/gc or next; + /$numRE/gco or next; $xlast = $1; - while(/([0-9]+) ($numRE)/gc) + while(/([0-9]+) $numRE/gco) { my $idx = $1; my $point = $2; @@ -200,7 +197,7 @@ sub mainThread { newCurve("", ""); } - push @{$curves[$idx]->{"data"}}, [$xlast, $point]; + push @{$curves[$idx]}, [$xlast, $point]; } } @@ -251,14 +248,13 @@ sub mainThread { sub cutOld { my ($oldestx) = @_; - foreach (@curves) - { - my $xy = $_->{"data"}; - if( @$xy ) + foreach my $xy (@curves) + { + if( @$xy > 1 ) { - my $firstInWindow = first_index {$_->[0] >= $oldestx} @$xy; - splice( @$xy, 0, $firstInWindow ) unless $firstInWindow == -1; + my $firstInWindow = first_index {$_->[0] >= $oldestx} @{$xy}[1..$#$xy]; + splice( @$xy, 1, $firstInWindow ) unless $firstInWindow == -1; } } } @@ -268,14 +264,16 @@ sub plotStoredData my ($xmin, $xmax) = @_; print PIPE "set xrange [$xmin:$xmax]\n" if defined $xmin; - my @extraopts = map {$_->{"extraopts"}} grep {@{$_->{"data"}}} @curves; + # get the options for those curves that have any data + my @extraopts = map {$_->[0]} grep {@$_ > 1} @curves; + print PIPE 'plot ' . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; - foreach my $curve (@curves) + foreach my $buf (@curves) { - my $buf = $curve->{"data"}; - next unless @$buf; - for my $elem (@$buf) { + # send each point to gnuplot. Ignore the first "point" since it's the + # options string + for my $elem (@{$buf}[1..$#$buf]) { my ($x, $y) = @$elem; print PIPE "$x $y\n"; } @@ -289,10 +287,14 @@ sub newCurve() if($title) { $opts = "title \"$title\" $opts" } else { $opts = "notitle $opts" } - $newpoint = [] unless defined $newpoint; - push ( @curves, - {"extraopts" => " $opts", - "data" => $newpoint} ); + if( defined $newpoint ) + { + push @curves, [" $opts", $newpoint]; + } + else + { + push @curves, [" $opts"]; + } } sub usage { From 33f62a843829b3ded5dd6ba05596a19a7e454827 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 15 Sep 2009 12:13:59 -0700 Subject: [PATCH 036/270] only set X11 terminal if we're not making a hardcopy Ignore-this: 72ff2e9c96debe696944ad584eec32fd darcs-hash:20090915191359-0cb85-21cb3091eedfb7c69818028340b89f050e4fea7e.gz --- driveGnuPlots.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 21ef92d..1162628 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -134,8 +134,11 @@ sub mainThread { $temphardcopyfile = "/tmp/$temphardcopyfile"; print PIPE "set output \"$temphardcopyfile\"\n"; } + else + { + print PIPE "set terminal x11\n"; + } - print PIPE "set terminal x11\n"; print PIPE "set xtics\n"; if($options{"y2"}) { From 3e6fabaf971cf214954b6a2cd0346c71544ee8a8 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 15 Sep 2009 12:44:23 -0700 Subject: [PATCH 037/270] fix handling of empty curves Ignore-this: b898c03e4df23a2d9c6c5fad7065aff4 darcs-hash:20090915194423-0cb85-e00bbfe44ec500ed844e2275571a9170bcd5e4aa.gz --- driveGnuPlots.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 1162628..d535735 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -268,11 +268,12 @@ sub plotStoredData print PIPE "set xrange [$xmin:$xmax]\n" if defined $xmin; # get the options for those curves that have any data - my @extraopts = map {$_->[0]} grep {@$_ > 1} @curves; + my @nonemptyCurves = grep {@$_ > 1} @curves; + my @extraopts = map {$_->[0]} @nonemptyCurves; print PIPE 'plot ' . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; - foreach my $buf (@curves) + foreach my $buf (@nonemptyCurves) { # send each point to gnuplot. Ignore the first "point" since it's the # options string From aed7b353ea58b94f27454b873aa880f8f4170bb8 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 15 Sep 2009 16:25:13 -0700 Subject: [PATCH 038/270] driveGnuPlots can dump its output to stdout for debugging Ignore-this: 209901071caa48bd58c68edd1fae9eaf darcs-hash:20090915232513-0cb85-1fe5f99c0825a0ecb48f554b266717140a0f1a36.gz --- driveGnuPlots.pl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index d535735..7a7af8e 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -40,7 +40,8 @@ GetOptions(\%options, "y2max=f", "y2=i@", "hardcopy=s", - "help"); + "help", + "dump"); # set up plotting style my $style = ""; @@ -108,7 +109,14 @@ sub mainThread { my $dopersist = ""; $dopersist = "--persist" if(!$options{"stream"}); - open PIPE, "|gnuplot $dopersist" || die "Can't initialize gnuplot\n"; + if(exists $options{"dump"}) + { + *PIPE = *STDOUT; + } + else + { + open PIPE, "|gnuplot $dopersist" || die "Can't initialize gnuplot\n"; + } autoflush PIPE 1; my $temphardcopyfile; From 747d620b48f3219f850d2b69608aeb6bbc7508ca Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 3 Dec 2009 11:22:33 -0800 Subject: [PATCH 039/270] fixed use os ymin/ymax cmdline args. Added xmin/xmax args Ignore-this: 88c1704b78df6082baf4e6249f3b6cd3 darcs-hash:20091203192233-0cb85-9c624b26e1af5ad7ae07be83f0f19057692114f4.gz --- driveGnuPlots.pl | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 7a7af8e..fc79570 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -36,6 +36,8 @@ GetOptions(\%options, "xlen=f", "ymin=f", "ymax=f", + "xmin=f", + "xmax=f", "y2min=f", "y2max=f", "y2=i@", @@ -152,9 +154,10 @@ sub mainThread { { print PIPE "set ytics nomirror\n"; print PIPE "set y2tics\n"; - print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if $options{"y2max"}; + print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if( $options{"y2min"} || $options{"y2max"} ); } - print PIPE "set yrange [". $options{"ymin"} . ":" . $options{"ymax"} ."]\n" if $options{"y2max"}; + print PIPE "set xrange [". $options{"xmin"} . ":" . $options{"xmax"} ."]\n" if( $options{"xmin"} || $options{"xmax"} );; + print PIPE "set yrange [". $options{"ymin"} . ":" . $options{"ymax"} ."]\n" if( $options{"ymin"} || $options{"ymax"} );; print PIPE "set style data $style\n"; print PIPE "set grid\n"; @@ -320,10 +323,12 @@ sub usage { --title xxx Set the title of the plot --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves --xlen xxx Set the size of the x-window to plot - --ymin xxx Set the range for the y axis. Both or neither of these have to be specified - --ymax xxx Set the range for the y axis. Both or neither of these have to be specified - --y2min xxx Set the range for the y2 axis. Both or neither of these have to be specified - --y2max xxx Set the range for the y2 axis. Both or neither of these have to be specified + --xmin xxx Set the range for the x axis. These are ignored in a streaming plot + --xmax xxx Set the range for the x axis. These are ignored in a streaming plot + --ymin xxx Set the range for the y axis. + --ymax xxx Set the range for the y axis. + --y2min xxx Set the range for the y2 axis. + --y2max xxx Set the range for the y2 axis. --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename OEF From 59fdc08dc69858c979cd191efc9a711a9a3a458f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Dec 2009 14:22:52 -0800 Subject: [PATCH 040/270] when grabbing data either from the thread-safe queue or from <>, I should be using //, not || Ignore-this: 853ee4746850b2da83006e06ea4dc82b darcs-hash:20091206222252-0cb85-cbe476e37cd152cf1952356df6534ab4fd2a4e3d.gz --- driveGnuPlots.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index fc79570..db57e3a 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -190,7 +190,7 @@ sub mainThread { my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/; my $xlast; - while( $_ = ($dataQueue && $dataQueue->dequeue()) || <> ) + while( $_ = ($dataQueue && $dataQueue->dequeue()) // <> ) { if($_ ne "Plot now") { From d4ddf5f001d09e5a4bfa86f3a2e3c9673eaf842a Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Dec 2009 14:23:21 -0800 Subject: [PATCH 041/270] compile the "number" regext only once Ignore-this: a47b92945ee7391597dfd931e9367a66 darcs-hash:20091206222321-0cb85-97e4afd4ee0df75d54147a661a76a2fe097e9a8c.gz --- driveGnuPlots.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index db57e3a..285d2a7 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -186,8 +186,8 @@ sub mainThread { } } - # regexp for a possibly floating point, possibly scientific notation number - my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/; + # regexp for a possibly floating point, possibly scientific notation number, fully captured + my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/o; my $xlast; while( $_ = ($dataQueue && $dataQueue->dequeue()) // <> ) From 8834e11a87965fec648898a7b8de9678c2bd4930 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Dec 2009 14:55:31 -0800 Subject: [PATCH 042/270] when streaming, don't plot unless there's new data Ignore-this: ad73a697f4fdff7f269321aab8ea78f9 darcs-hash:20091206225531-0cb85-8951ac75504fb61c7ee2e9c7b20fae76f8fe4196.gz --- driveGnuPlots.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 285d2a7..bde67df 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -189,11 +189,14 @@ sub mainThread { # regexp for a possibly floating point, possibly scientific notation number, fully captured my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/o; my $xlast; + my $haveNewData; while( $_ = ($dataQueue && $dataQueue->dequeue()) // <> ) { if($_ ne "Plot now") { + $haveNewData = 1; + # parse the incoming data lines. The format is # x idx0 dat0 idx1 dat1 .... # where idxX is the index of the curve that datX corresponds to @@ -217,6 +220,9 @@ sub mainThread { elsif($options{"stream"} && defined $xlast) { + next unless $haveNewData; + $haveNewData = undef; + cutOld($xlast - $xwindow); plotStoredData($xlast - $xwindow, $xlast); } From 0a2226594a5bd7fccea2a3d4cdf636e78d8a7d77 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 4 Nov 2009 18:20:51 -0800 Subject: [PATCH 043/270] fixed a bug in the drivegnuplot scripts. when a new curve is added, they now make sure to add all the curves leading up to those. So if I'm trying to create curve 5, it'll create 0,1,2,3,4 if they aren't there --- driveGnuPlots.pl | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index bde67df..493c0c1 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -182,7 +182,7 @@ sub mainThread { } else { - newCurve("", $str); + newCurve("", $str, undef, $y2idx); } } @@ -208,11 +208,7 @@ sub mainThread { my $idx = $1; my $point = $2; - # if this curve index doesn't exist, create curve up-to this index - while(!exists $curves[$idx]) - { - newCurve("", ""); - } + newCurve("", "", undef, $idx); push @{$curves[$idx]}, [$xlast, $point]; } @@ -304,20 +300,43 @@ sub plotStoredData sub newCurve() { - my ($title, $opts, $newpoint) = @_; + my ($title, $opts, $newpoint, $idx) = @_; + + # if this curve index doesn't exist, create curve up-to this index + if(defined $idx) + { + while(!exists $curves[$idx]) + { + pushNewEmptyCurve(); + } + } + else + { + # if we're not given an index, create a new one at the end, and fill it in + pushNewEmptyCurve(); + $idx = $#curves; + } + if($title) { $opts = "title \"$title\" $opts" } else { $opts = "notitle $opts" } if( defined $newpoint ) { - push @curves, [" $opts", $newpoint]; + $curves[$idx] = [" $opts", $newpoint]; } else { - push @curves, [" $opts"]; + $curves[$idx] = [" $opts"]; } } +sub pushNewEmptyCurve +{ + my $opts = "notitle "; + push @curves, [" $opts"]; +} + + sub usage { print "Usage: $0 \n"; print < Date: Fri, 20 Nov 2009 21:56:41 -0800 Subject: [PATCH 044/270] drivegnuplots: don't overwrite previous data-to-plot Ignore-this: 4f401c72bf7e92ee4877955ba301d49b darcs-hash:20091121055641-0cb85-415016115f3beb233730cd79fa8b1b78bc87ff7e.gz --- driveGnuPlots.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 493c0c1..b7c9b47 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -208,7 +208,7 @@ sub mainThread { my $idx = $1; my $point = $2; - newCurve("", "", undef, $idx); + newCurve("", "", undef, $idx) unless exists $curves[$idx]; push @{$curves[$idx]}, [$xlast, $point]; } From 772f07d3c7ae8aff620d46f2e0f9f37e683c1142 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 3 Dec 2009 11:37:50 -0800 Subject: [PATCH 045/270] minor fixes to the hardcopy output code --- driveGnuPlots.pl | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index b7c9b47..3ba5ee8 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -130,18 +130,20 @@ sub mainThread { ($outputfileType) = $outputfile =~ /\.(ps|pdf|png)$/; if(!$outputfileType) { die("Only .ps, .pdf and .png supported\n"); } - if ($outputfileType eq "png") - { - print PIPE "set terminal png\n"; - } - else - { - print PIPE "set terminal postscript solid color landscape 10\n"; - } # write to a temporary file first $temphardcopyfile = $outputfile; $temphardcopyfile =~ s{/}{_}g; $temphardcopyfile = "/tmp/$temphardcopyfile"; + if ($outputfileType eq "png") + { + print PIPE "set terminal png\n"; + $temphardcopyfile .= '.png'; + } + else + { + print PIPE "set terminal postscript solid color landscape 10\n"; + $temphardcopyfile .= '.ps'; + } print PIPE "set output \"$temphardcopyfile\"\n"; } else @@ -242,6 +244,7 @@ sub mainThread { usleep(100_000) until -e $temphardcopyfile; usleep(100_000) until(system("fuser -s $temphardcopyfile")); + print "Finished gnuplotting. Converting...\n"; if($outputfileType eq "pdf") { system("ps2pdf $temphardcopyfile $outputfile"); @@ -250,7 +253,7 @@ sub mainThread { { system("mv $temphardcopyfile $outputfile"); } - printf "Wrote output to $outputfile\n"; + print "Wrote output to $outputfile\n"; return; } From d6e1dc56436bd708d765bceac9bddf582be30e4a Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Dec 2009 12:48:50 -0800 Subject: [PATCH 046/270] usage is now at the front, not at the end of the file Ignore-this: 86899869bed3fd0c62b04f86f2ee7943 darcs-hash:20091206204850-0cb85-8fd04b4dce799512f1b6f0223e063846fdc4e6c8.gz --- driveGnuPlots.pl | 52 +++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 3ba5ee8..bfd7cc9 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -15,6 +15,26 @@ autoflush STDOUT 1; # options my @curves = (); +my $usage = < + --[no]stream Do [not] display the data a point at a time, as it comes in + --[no]lines Do [not] draw lines to connect consecutive points + --xlabel xxx Set x-axis label + --ylabel xxx Set y-axis label + --y2label xxx Set y2-axis label + --title xxx Set the title of the plot + --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves + --xlen xxx Set the size of the x-window to plot + --xmin xxx Set the range for the x axis. These are ignored in a streaming plot + --xmax xxx Set the range for the x axis. These are ignored in a streaming plot + --ymin xxx Set the range for the y axis. + --ymax xxx Set the range for the y axis. + --y2min xxx Set the range for the y2 axis. + --y2max xxx Set the range for the y2 axis. + --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed + --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename +OEF + # stream in the data by default # point plotting by default my %options = ( "stream" => 1, @@ -43,7 +63,7 @@ GetOptions(\%options, "y2=i@", "hardcopy=s", "help", - "dump"); + "dump") or die($usage); # set up plotting style my $style = ""; @@ -54,8 +74,7 @@ if(!$style) { $style = "points"; } if( defined $options{"help"} ) { - usage(); - return; + die($usage); } # now start the data acquisition and plotting threads @@ -70,8 +89,7 @@ if($options{"stream"}) } if( !defined $options{"xlen"} ) { - usage(); - die("Must specify the size of the moving x-window. Doing nothing\n"); + die("$usage\nMust specify the size of the moving x-window. Doing nothing\n"); } $xwindow = $options{"xlen"}; @@ -338,27 +356,3 @@ sub pushNewEmptyCurve my $opts = "notitle "; push @curves, [" $opts"]; } - - -sub usage { - print "Usage: $0 \n"; - print < Date: Sun, 6 Dec 2009 14:20:27 -0800 Subject: [PATCH 047/270] moved the @curves declaration further down, closer to where it is used Ignore-this: f51fd22e3519c6dae6020e3721d70df8 darcs-hash:20091206222027-0cb85-0668ea7d622ba67d9cd78bebfdbcd37f11cae5f0.gz --- driveGnuPlots.pl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index bfd7cc9..fbc4ba0 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -10,11 +10,6 @@ use Thread::Queue; autoflush STDOUT 1; -# list containing the plot data. Each element is a reference to a list, -# representing the data for one curve. The first "point" is a string of plot -# options -my @curves = (); - my $usage = < --[no]stream Do [not] display the data a point at a time, as it comes in @@ -77,6 +72,12 @@ if( defined $options{"help"} ) die($usage); } + +# list containing the plot data. Each element is a reference to a list, +# representing the data for one curve. The first "point" is a string of plot +# options +my @curves = (); + # now start the data acquisition and plotting threads my $dataQueue; my $xwindow; From 153045d95a480a234213f616423b24ddf568214f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Dec 2009 14:20:51 -0800 Subject: [PATCH 048/270] don't need to autoflush STDOUT since I'm not using it Ignore-this: 2a146ee2c7f2d31b301b8dbbc9afdcb1 darcs-hash:20091206222051-0cb85-f1b9ce050557a2b9b6797b8a3ece9386972a405e.gz --- driveGnuPlots.pl | 2 -- 1 file changed, 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index fbc4ba0..bc2eb8d 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -8,8 +8,6 @@ use Data::Dumper; use threads; use Thread::Queue; -autoflush STDOUT 1; - my $usage = < --[no]stream Do [not] display the data a point at a time, as it comes in From 0a57f3b2fc14962c2861c5b81d75940ccc961afd Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Dec 2009 14:22:03 -0800 Subject: [PATCH 049/270] reindented, fixed up usage comment Ignore-this: 1e28fffd7e4f8297adc7ae12ab39ede5 darcs-hash:20091206222203-0cb85-df50944ed972d35e771b5be2a13fdd3b66d2f0f0.gz --- driveGnuPlots.pl | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index bc2eb8d..29bb447 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -10,22 +10,31 @@ use Thread::Queue; my $usage = < - --[no]stream Do [not] display the data a point at a time, as it comes in + --[no]stream Do [not] display the data a point at a time, as it + comes in --[no]lines Do [not] draw lines to connect consecutive points + --[no]points Do [not] draw points --xlabel xxx Set x-axis label --ylabel xxx Set y-axis label --y2label xxx Set y2-axis label --title xxx Set the title of the plot - --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves + --legend xxx Set the label for a curve plot. Give this option multiple + times for multiple curves --xlen xxx Set the size of the x-window to plot - --xmin xxx Set the range for the x axis. These are ignored in a streaming plot - --xmax xxx Set the range for the x axis. These are ignored in a streaming plot + --xmin xxx Set the range for the x axis. These are ignored in a + streaming plot + --xmax xxx Set the range for the x axis. These are ignored in a + streaming plot --ymin xxx Set the range for the y axis. --ymax xxx Set the range for the y axis. --y2min xxx Set the range for the y2 axis. --y2max xxx Set the range for the y2 axis. - --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed - --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename + --y2 xxx Plot the data with this index on the y2 axis. These are + 0-indexed + --hardcopy xxx If not streaming, output to a file specified here. Format + inferred from filename + --dump Instead of printing to gnuplot, print to STDOUT. For + debugging. OEF # stream in the data by default From 598a912fbfe011dc48e71804b3bde57b32a4651d Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Dec 2009 14:49:44 -0800 Subject: [PATCH 050/270] driveGnuPlots.pl now has --domain and --dataindex options. These make driveGnuPlots_simple.pl Ignore-this: 2b8de7b779d6896168a5771d54d56568 obsolete, since it's now a special case of driveGnuPlots.pl darcs-hash:20091206224944-0cb85-dc8089f2146c401ef51bb86a2d507b9e85421a5a.gz --- driveGnuPlots.pl | 95 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 14 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 29bb447..26e8738 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -10,6 +10,31 @@ use Thread::Queue; my $usage = < + + --[no]domain If enabled, the first element of each line is the + domain variable. If not, the point index is used + + --[no]dataindex If enabled, each data point is preceded by the index + of the data set that point corresponds to. If not + enabled, the order of the point is used. + +As an example, if line 3 of the input is "0 9 1 20" + '--nodomain --nodataindex' would parse the 4 numbers as points in 4 + different curves at x=3 + + '--domain --nodataindex' would parse the 4 numbers as points in 3 different + curves at x=0. Here, 0 is the x-variable and 9,1,20 are the data values + + '--nodomain --dataindex' would parse the 4 numbers as points in 2 different + curves at x=3. Here 0 and 1 are the data indices and 9 and 20 are the + data values + + '--domain --dataindex' would parse the 4 numbers as a single point at + x=0. Here 9 is the data index and 1 is the data value. 20 is an extra + value, so it is ignored. If another value followed 20, we'd get another + point in curve number + + --[no]stream Do [not] display the data a point at a time, as it comes in --[no]lines Do [not] draw lines to connect consecutive points @@ -39,15 +64,19 @@ OEF # stream in the data by default # point plotting by default -my %options = ( "stream" => 1, - "points" => 0, - "lines" => 0, - "ymin" => "", - "ymax" => "", - "y2min" => "", - "y2max" => ""); +my %options = ( "stream" => 1, + "domain" => 0, + "dataindex" => 0, + "points" => 0, + "lines" => 0, + "ymin" => "", + "ymax" => "", + "y2min" => "", + "y2max" => ""); GetOptions(\%options, "stream!", + "domain!", + "dataindex!", "lines!", "points!", "legend=s@", @@ -107,7 +136,15 @@ if($options{"stream"}) while(<>) { + # place every line of input to the queue, so that the plotting thread can process it. $dataQueue->enqueue($_); + + # if we are using an implicit domain (x = line number), then we send it on the data queue also, + # since $. is not meaningful in the plotting thread + if(!$options{domain}) + { + $dataQueue->enqueue($.); + } } $dataQueue->enqueue("Plot now"); @@ -228,17 +265,47 @@ sub mainThread { # parse the incoming data lines. The format is # x idx0 dat0 idx1 dat1 .... # where idxX is the index of the curve that datX corresponds to - /$numRE/gco or next; - $xlast = $1; + # + # $options{domain} indicates whether the initial 'x' is given or not (if not, the line + # number is used) + # $options{dataindex} indicates whether idxX is given or not (if not, the point order in the + # line is used) - while(/([0-9]+) $numRE/gco) + if($options{domain}) { - my $idx = $1; - my $point = $2; + /$numRE/go or next; + $xlast = $1; + } + else + { + # since $. is not meaningful in the plotting thread if we're using the data queue, we pass + # $. on the data queue in that case. This construct pulls it from the queue if we're using + # it, otherwise it uses $. directly + $xlast = ($dataQueue && $dataQueue->dequeue()) // $.; + } - newCurve("", "", undef, $idx) unless exists $curves[$idx]; + if($options{dataindex}) + { + while(/([0-9]+)\s+$numRE/go) + { + my $idx = $1; + my $point = $2; - push @{$curves[$idx]}, [$xlast, $point]; + newCurve("", "", undef, $idx) unless exists $curves[$idx]; + + push @{$curves[$idx]}, [$xlast, $point]; + } + } + else + { + my $idx = 0; + foreach my $point (/$numRE/go) + { + newCurve("", "", undef, $idx) unless exists $curves[$idx]; + + push @{$curves[$idx]}, [$xlast, $point]; + $idx++; + } } } From c92e011de0bba735ceb7ac454f4528f47e68c312 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 18 Dec 2009 12:48:15 -0800 Subject: [PATCH 051/270] do not stream by default Ignore-this: f8099a01a733f1a660236e26b0897568 darcs-hash:20091218204815-0cb85-a3bc77724d36c755ebfaa61c5cf53c5b3bfe4f28.gz --- driveGnuPlots.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 26e8738..6055af1 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -62,9 +62,9 @@ As an example, if line 3 of the input is "0 9 1 20" debugging. OEF -# stream in the data by default +# do not stream in the data by default # point plotting by default -my %options = ( "stream" => 1, +my %options = ( "stream" => 0, "domain" => 0, "dataindex" => 0, "points" => 0, From 0d689edbf92addab9696c375c37edbe7c03ae50e Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 19 Dec 2009 19:14:11 -0800 Subject: [PATCH 052/270] reworked hardcopy output. No longer writing to a tmp file first Ignore-this: 6bcb476652cd7d3f532fe5326ff18fca darcs-hash:20091220031411-0cb85-4749f31184e76afb16dc974a93d1214febbb9da3.gz --- driveGnuPlots.pl | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 6055af1..9d5e976 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -184,7 +184,6 @@ sub mainThread { } autoflush PIPE 1; - my $temphardcopyfile; my $outputfile; my $outputfileType; if( defined $options{"hardcopy"}) @@ -193,21 +192,13 @@ sub mainThread { ($outputfileType) = $outputfile =~ /\.(ps|pdf|png)$/; if(!$outputfileType) { die("Only .ps, .pdf and .png supported\n"); } -# write to a temporary file first - $temphardcopyfile = $outputfile; - $temphardcopyfile =~ s{/}{_}g; - $temphardcopyfile = "/tmp/$temphardcopyfile"; - if ($outputfileType eq "png") - { - print PIPE "set terminal png\n"; - $temphardcopyfile .= '.png'; - } - else - { - print PIPE "set terminal postscript solid color landscape 10\n"; - $temphardcopyfile .= '.ps'; - } - print PIPE "set output \"$temphardcopyfile\"\n"; + my %terminalOpts = + ( ps => 'postscript solid color landscape 10', + pdf => 'pdfcairo solid color font ",10" size 11in,8.5in', + png => 'png' ); + + print PIPE "set terminal $terminalOpts{$outputfileType}\n"; + print PIPE "set output \"$outputfile\"\n"; } else { @@ -334,18 +325,9 @@ sub mainThread { 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")); + usleep(100_000) until -e $outputfile; + usleep(100_000) until(system("fuser -s $outputfile")); - print "Finished gnuplotting. Converting...\n"; - if($outputfileType eq "pdf") - { - system("ps2pdf $temphardcopyfile $outputfile"); - } - else - { - system("mv $temphardcopyfile $outputfile"); - } print "Wrote output to $outputfile\n"; return; } From e16af8103a491cd27aa885a635d2cf3c5068e3e6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 10 Jan 2010 23:45:41 -0800 Subject: [PATCH 053/270] clarified comment --- driveGnuPlots.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index 9d5e976..b0c5911 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -310,7 +310,7 @@ sub mainThread { } } - # read in all of the data + # finished reading in all of the data if($options{"stream"}) { print PIPE "exit;\n"; From 8d38a2c053cdd7dcd8df0fda6167fdd8e1d2c759 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 10 Jan 2010 23:46:53 -0800 Subject: [PATCH 054/270] skip all lines that start with '#'. Now I can have self-plotting data files using #! --- driveGnuPlots.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/driveGnuPlots.pl b/driveGnuPlots.pl index b0c5911..d37492c 100755 --- a/driveGnuPlots.pl +++ b/driveGnuPlots.pl @@ -249,6 +249,8 @@ sub mainThread { while( $_ = ($dataQueue && $dataQueue->dequeue()) // <> ) { + next if /^#/o; + if($_ ne "Plot now") { $haveNewData = 1; From a69b2d6d4f35903650de8424f2c76dca7b78126c Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 11 Jan 2010 21:56:09 -0800 Subject: [PATCH 055/270] renamed script to feedGnuplot.pl --- driveGnuPlots.pl => feedGnuplot.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename driveGnuPlots.pl => feedGnuplot.pl (100%) diff --git a/driveGnuPlots.pl b/feedGnuplot.pl similarity index 100% rename from driveGnuPlots.pl rename to feedGnuplot.pl From 7c9c9b82be882a3c48dc0b1bff93150268ae3dd0 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 12 Jan 2010 21:39:02 -0800 Subject: [PATCH 056/270] initial commit of the README --- README | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 0000000..b7e5d8f --- /dev/null +++ b/README @@ -0,0 +1,62 @@ +feedGnuplot README +================== + +This is a flexible, command-line-oriented frontend to Gnuplot. It creates +plots from data coming in on STDIN or given in a filename passed on the +commandline. Various data representations are supported, as is hardcopy +output and streaming display of live data. A simple example: + +seq 5 | awk '{print 2*$1, $1*$1}' | +feedGnuplot.pl --lines --points --legend "data 0" --title "Test plot" --y2 1 + +You should see a plot with two curves (one on the y1 axis and the other on +the y2 axis), a legend and a title. The first line of the example generates +some data to plot and the second reads it in from STDIN and generates the +plot. None of the commandline-options are required for the most basic +plotting. Input parsing is flexible; every line need not have the same +number of points. New curves will be created as needed. + +By default, the line number of the incoming data is used for the x-axis. To +plot an x-y dataset, feed in the x values as the first element in every line +and pass in --domain. With the previous example: + +seq 5 | awk '{print 2*$1, $1*$1}' | +feedGnuplot.pl --domain --lines --points --legend "data 0" --title "Test plot" --y2 1 + +we get only one curve, with different x values. As many points as desired +can appear on a single line, but all points on a line are associated with +the X value that starts that line. + +By default, each column represents a separate curve. If sparse data is to be +plotted, this is undesireable. With the --dataindex option, each point in +the input is preceded by an integer identifying the curve the point belongs +to. With the previous example: + +seq 5 | awk '{print 2*$1, $1*$1}' | +feedGnuplot.pl --dataindex --lines --points --legend "data 0" --title "Test plot" --y2 1 + +we get 5 different curves with one point in each. The first column, as +produced by awk, is '2,4,6,8,10'. These are interpreted as the indices of +the curves to be plotted. The feedGnuplot.pl script created 11 different +curves (0-10 inclusive), but only 5 of them were given any data. Note that +with this invocation of the example no legend was created. This is because +the legend commandline parameters are applied in order to curves +0,1,2,... Above, "data 0" applied to curve 0, which had no data. If we +passed in --legend "data 0" --legend "data 1" --legend "data 2", a legend +would be created with "data 2" labeled, but no labels for the other +curves. As many points as desired can appear on a single line, and --domain +can be used together with --dataindex. + +The script is able to produce hardcopy output with "--hardcopy +outputfile". The output type is inferred from the filename with .ps, .pdf +and .png currently supported. + +If something is producing data in realtime, feedGnuplot.pl can be used to +produce a realtime display. The --stream option should be passed in along +with "--xlen windowsize". This will produce a scrolling window containing +the last windowsize-worth of data (windowsize has the units of the x axis, +whether it is a point index or the passed-in data). The scrolling window is +updated at 1 Hz, so the script can handle rapidly-incoming data without +spending all of its time replotting. + +For more information, invoke with --help, or read the source. From 6b169e03a8143d13411c6783768386285de498e0 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 12 Jan 2010 21:54:49 -0800 Subject: [PATCH 057/270] Now reading the version of gnuplot on the system, and not using --persist on versions of gnuplot too old to support it. --- feedGnuplot.pl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index d37492c..070aebe 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -8,6 +8,16 @@ use Data::Dumper; use threads; use Thread::Queue; +open(GNUPLOT_VERSION, "gnuplot --version |"); +my ($gnuplotVersion) = =~ /gnuplot\s*([0-9]*\.[0-9]*)/; +if(!$gnuplotVersion) +{ + print STDERR "Couldn't find the version of gnuplot. Does it work? Trying anyway...\n"; + $gnuplotVersion = 0; +} + +close(GNUPLOT_VERSION); + my $usage = < @@ -172,7 +182,11 @@ sub plotThread sub mainThread { local *PIPE; my $dopersist = ""; - $dopersist = "--persist" if(!$options{"stream"}); + + if($gnuplotVersion >= 4.3) + { + $dopersist = "--persist" if(!$options{"stream"}); + } if(exists $options{"dump"}) { From c6ee73f97fca1b49e24e69d751759f8ba5acc985 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 14 Jan 2010 14:34:58 -0800 Subject: [PATCH 058/270] spaced out the --help message --- feedGnuplot.pl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 070aebe..4a1aea7 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -47,27 +47,44 @@ As an example, if line 3 of the input is "0 9 1 20" --[no]stream Do [not] display the data a point at a time, as it comes in + --[no]lines Do [not] draw lines to connect consecutive points + --[no]points Do [not] draw points + --xlabel xxx Set x-axis label + --ylabel xxx Set y-axis label + --y2label xxx Set y2-axis label + --title xxx Set the title of the plot + --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves + --xlen xxx Set the size of the x-window to plot + --xmin xxx Set the range for the x axis. These are ignored in a streaming plot + --xmax xxx Set the range for the x axis. These are ignored in a streaming plot + --ymin xxx Set the range for the y axis. + --ymax xxx Set the range for the y axis. + --y2min xxx Set the range for the y2 axis. + --y2max xxx Set the range for the y2 axis. + --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed + --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename + --dump Instead of printing to gnuplot, print to STDOUT. For debugging. OEF From 5e44f777fb934743441767bb13ce0ff329e1b036 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 14 Jan 2010 14:45:24 -0800 Subject: [PATCH 059/270] Allow to specify a limit on the number of curves. --- feedGnuplot.pl | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 4a1aea7..da9979f 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -85,6 +85,11 @@ As an example, if line 3 of the input is "0 9 1 20" --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename + --maxcurves xxx The maximum allowed number of curves. This is 10 by default, + but can be reset with this option. This exists purely to + prevent perl from allocating all of the system's memory when + reading bogus data + --dump Instead of printing to gnuplot, print to STDOUT. For debugging. OEF @@ -99,7 +104,9 @@ my %options = ( "stream" => 0, "ymin" => "", "ymax" => "", "y2min" => "", - "y2max" => ""); + "y2max" => "", + "maxcurves" => 10); + GetOptions(\%options, "stream!", "domain!", @@ -120,6 +127,7 @@ GetOptions(\%options, "y2max=f", "y2=i@", "hardcopy=s", + "maxcurves=i", "help", "dump") or die($usage); @@ -413,6 +421,13 @@ sub newCurve() { my ($title, $opts, $newpoint, $idx) = @_; + if(scalar @curves >= $options{maxcurves}) + { + say STDERR "Tried to exceed the --maxcurves setting."; + say STDERR "Invoke with a higher --maxcurves limit if you really want to do this."; + return; + } + # if this curve index doesn't exist, create curve up-to this index if(defined $idx) { From 7580ea0656717799b2e94c9bf4e591454609cb41 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 14 Jan 2010 15:09:33 -0800 Subject: [PATCH 060/270] bumped up the default maxcurves setting --- feedGnuplot.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index da9979f..e944a66 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -85,7 +85,7 @@ As an example, if line 3 of the input is "0 9 1 20" --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename - --maxcurves xxx The maximum allowed number of curves. This is 10 by default, + --maxcurves xxx The maximum allowed number of curves. This is 100 by default, but can be reset with this option. This exists purely to prevent perl from allocating all of the system's memory when reading bogus data @@ -105,7 +105,7 @@ my %options = ( "stream" => 0, "ymax" => "", "y2min" => "", "y2max" => "", - "maxcurves" => 10); + "maxcurves" => 100); GetOptions(\%options, "stream!", From 59da3af4b06522f2a0ce518371be883480bb27a6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 25 Jan 2010 21:35:26 -0800 Subject: [PATCH 061/270] added note to the README about the original version --- README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README b/README index b7e5d8f..4e13a8d 100644 --- a/README +++ b/README @@ -60,3 +60,8 @@ updated at 1 Hz, so the script can handle rapidly-incoming data without spending all of its time replotting. For more information, invoke with --help, or read the source. + + +This program is originally based on the driveGnuPlots.pl script from +Thanassis Tsiodras. It is available from his site at +http://users.softlab.ece.ntua.gr/~ttsiod/gnuplotStreaming.html From 68843f226efd587ebef6ed6b8f2601b7a7ff2b5e Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 5 Feb 2010 12:05:52 -0800 Subject: [PATCH 062/270] extra logic to correctly parse options given with a #! in a self-plotting data file --- feedGnuplot.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index e944a66..dd18f3d 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -94,6 +94,16 @@ As an example, if line 3 of the input is "0 9 1 20" debugging. OEF +# if I'm using a self-plotting data file with a #! line, then $ARGV[0] will contain ALL of the +# options and $ARGV[1] will contain the data file to plot. In this case I need to split $ARGV[0] so +# that GetOptions() can parse it correctly. On the other hand, if I'm plotting normally (not with +# #!) a file with spaces in the filename, I don't want to split the filename. Hopefully this logic +# takes care of both those cases. +if(exists $ARGV[0] && !-r $ARGV[0]) +{ + unshift @ARGV, split(/\s+/, shift(@ARGV)); +} + # do not stream in the data by default # point plotting by default my %options = ( "stream" => 0, From da4dd9bd439080cb699b982698d66137809d5b09 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 5 Feb 2010 14:33:46 -0800 Subject: [PATCH 063/270] improved --help message slightly --- feedGnuplot.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index dd18f3d..10fcbab 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -19,7 +19,10 @@ if(!$gnuplotVersion) close(GNUPLOT_VERSION); my $usage = < +Usage: $0 [options] file1 file2 ... + any number of data files can be given on the cmdline. They will be processed + in sequence. If no data files are given, data will be read in from standard + input. --[no]domain If enabled, the first element of each line is the domain variable. If not, the point index is used From b0dc4fdd8673873a03e1b435e6207ba4deefd57b Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 11 Feb 2010 14:14:57 -0800 Subject: [PATCH 064/270] when streaming, xlen==0 ---> plot ALL the data, not just what is in a window --- feedGnuplot.pl | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 10fcbab..fed2ef4 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -66,7 +66,8 @@ As an example, if line 3 of the input is "0 9 1 20" --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves - --xlen xxx Set the size of the x-window to plot + --xlen xxx Set the size of the x-window to plot. Omit this or set it + to 0 to plot ALL the data --xmin xxx Set the range for the x axis. These are ignored in a streaming plot @@ -114,6 +115,7 @@ my %options = ( "stream" => 0, "dataindex" => 0, "points" => 0, "lines" => 0, + "xlen" => 0, "ymin" => "", "ymax" => "", "y2min" => "", @@ -172,11 +174,6 @@ if($options{"stream"}) { $options{"stream"} = undef; } - if( !defined $options{"xlen"} ) - { - die("$usage\nMust specify the size of the moving x-window. Doing nothing\n"); - } - $xwindow = $options{"xlen"}; $dataQueue = Thread::Queue->new(); my $addThr = threads->create(\&mainThread); @@ -359,8 +356,15 @@ sub mainThread { next unless $haveNewData; $haveNewData = undef; - cutOld($xlast - $xwindow); - plotStoredData($xlast - $xwindow, $xlast); + if( $options{"xlen"} ) + { + cutOld($xlast - $options{"xlen"}); + plotStoredData($xlast - $options{"xlen"}, $xlast); + } + else + { + plotStoredData(); + } } } From 0ae4fa9a21fa2b0ac502a1704fe83a4453b4adda Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 11 Feb 2010 16:06:40 -0800 Subject: [PATCH 065/270] Updated README to describe the new --xlen behavior --- README | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README b/README index 4e13a8d..9c1b4c4 100644 --- a/README +++ b/README @@ -52,12 +52,13 @@ outputfile". The output type is inferred from the filename with .ps, .pdf and .png currently supported. If something is producing data in realtime, feedGnuplot.pl can be used to -produce a realtime display. The --stream option should be passed in along -with "--xlen windowsize". This will produce a scrolling window containing +produce a realtime display by passing in the --stream option. The "--xlen +windowsize" option can be passed in also to plot a scrolling window, containing the last windowsize-worth of data (windowsize has the units of the x axis, -whether it is a point index or the passed-in data). The scrolling window is -updated at 1 Hz, so the script can handle rapidly-incoming data without -spending all of its time replotting. +whether it is a point index or the passed-in domain). If --xlen is omitted or +set to 0, all of the available data is plotted, with no moving window. The +realtime data is updated at 1 Hz, so the script can handle rapidly-incoming data +without spending all of its time replotting. For more information, invoke with --help, or read the source. From 3cddac38fe5572970ba4c1999b5e9fc93583c079 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 17 Feb 2010 21:34:51 -0800 Subject: [PATCH 066/270] slightly better README --- README | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README b/README index 9c1b4c4..cb2d308 100644 --- a/README +++ b/README @@ -51,14 +51,14 @@ The script is able to produce hardcopy output with "--hardcopy outputfile". The output type is inferred from the filename with .ps, .pdf and .png currently supported. -If something is producing data in realtime, feedGnuplot.pl can be used to -produce a realtime display by passing in the --stream option. The "--xlen -windowsize" option can be passed in also to plot a scrolling window, containing -the last windowsize-worth of data (windowsize has the units of the x axis, -whether it is a point index or the passed-in domain). If --xlen is omitted or -set to 0, all of the available data is plotted, with no moving window. The -realtime data is updated at 1 Hz, so the script can handle rapidly-incoming data -without spending all of its time replotting. +If live data is received in realtime, feedGnuplot.pl can be used to produce a +realtime display by passing in the --stream option. The "--xlen windowsize" +option can be passed in also to plot a scrolling window, containing the last +windowsize-worth of data (windowsize has the units of the x axis, whether it +is a point index or the passed-in domain). If --xlen is omitted or set to 0, +all of the available data is plotted, with no moving window. The realtime data +is updated at 1 Hz, so the script can handle rapidly-incoming data without +spending all of its time replotting. For more information, invoke with --help, or read the source. From ce4927e24dfad46e9592e4f88ce2322aaf1b6807 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 2 Mar 2010 17:13:12 -0800 Subject: [PATCH 067/270] a number in scientific notation can have an explicitly positive exponent --- feedGnuplot.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index fed2ef4..41b5356 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -292,7 +292,7 @@ sub mainThread { } # regexp for a possibly floating point, possibly scientific notation number, fully captured - my $numRE = qr/([-]?[0-9\.]+(?:e[-]?[0-9]+)?)/o; + my $numRE = qr/([-]?[0-9\.]+(?:e[-+]?[0-9]+)?)/o; my $xlast; my $haveNewData; From e68a65a88905273f5b0a8717c3d2225f22bb2de6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 28 Mar 2010 16:04:51 -0700 Subject: [PATCH 068/270] streaming redraw test no longer checks for $xlast, since if $haveNewData is set, $xlast is guaranteed to be set also. --- feedGnuplot.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 41b5356..bd45590 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -351,8 +351,9 @@ sub mainThread { } } - elsif($options{"stream"} && defined $xlast) + elsif($options{"stream"}) { + # only redraw a streaming plot if there's new data to plot next unless $haveNewData; $haveNewData = undef; From ac8cff2d6f5106546b493a58cf9ecb5cc11fa46d Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 28 Mar 2010 16:46:27 -0700 Subject: [PATCH 069/270] The first "point" is now a hash of options applying to that curve, instead of JUST the options string. This allows for more parameters to be stored --- feedGnuplot.pl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index bd45590..ae7f370 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -159,9 +159,9 @@ if( defined $options{"help"} ) } -# list containing the plot data. Each element is a reference to a list, -# representing the data for one curve. The first "point" is a string of plot -# options +# list containing the plot data. Each element is a reference to a list, representing the data for +# one curve. The first "point" is a hash describing various curve parameters. The rest are all +# references to lists of (x,y) tuples my @curves = (); # now start the data acquisition and plotting threads @@ -283,7 +283,7 @@ sub mainThread { my $str = " axes x1y2 linewidth 3"; if(exists $curves[$y2idx]) { - $curves[$y2idx][0] .= $str; + $curves[$y2idx][0]{"options"} .= $str; } else { @@ -419,14 +419,14 @@ sub plotStoredData # get the options for those curves that have any data my @nonemptyCurves = grep {@$_ > 1} @curves; - my @extraopts = map {$_->[0]} @nonemptyCurves; + my @extraopts = map {$_->[0]{"options"}} @nonemptyCurves; print PIPE 'plot ' . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; foreach my $buf (@nonemptyCurves) { # send each point to gnuplot. Ignore the first "point" since it's the - # options string + # curve options for my $elem (@{$buf}[1..$#$buf]) { my ($x, $y) = @$elem; print PIPE "$x $y\n"; @@ -466,16 +466,16 @@ sub newCurve() if( defined $newpoint ) { - $curves[$idx] = [" $opts", $newpoint]; + $curves[$idx] = [{"options" => " $opts"}, $newpoint]; } else { - $curves[$idx] = [" $opts"]; + $curves[$idx] = [{"options" => " $opts"}]; } } sub pushNewEmptyCurve { my $opts = "notitle "; - push @curves, [" $opts"]; + push @curves, [{"options" => " $opts"}]; } From a518711ad1e588881b56da99629eedf294f60137 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 28 Mar 2010 18:57:38 -0700 Subject: [PATCH 070/270] new option to force a monotonic x-coordinate --- feedGnuplot.pl | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index ae7f370..a0b9bd2 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -94,6 +94,12 @@ As an example, if line 3 of the input is "0 9 1 20" prevent perl from allocating all of the system's memory when reading bogus data + --monotonic If --domain is given, checks to make sure that the x- + coordinate in the input data is monotonically increasing. + If a given x-variable is in the past, all data currently + cached for this curve is purged. Without --monotonic, all + data is kept. No --monotonic by default + --dump Instead of printing to gnuplot, print to STDOUT. For debugging. OEF @@ -109,7 +115,8 @@ if(exists $ARGV[0] && !-r $ARGV[0]) } # do not stream in the data by default -# point plotting by default +# point plotting by default. +# no monotonicity checks by default my %options = ( "stream" => 0, "domain" => 0, "dataindex" => 0, @@ -143,6 +150,7 @@ GetOptions(\%options, "y2=i@", "hardcopy=s", "maxcurves=i", + "monotonic!", "help", "dump") or die($usage); @@ -333,9 +341,7 @@ sub mainThread { my $idx = $1; my $point = $2; - newCurve("", "", undef, $idx) unless exists $curves[$idx]; - - push @{$curves[$idx]}, [$xlast, $point]; + pushPoint($idx, [$xlast, $point]); } } else @@ -343,9 +349,7 @@ sub mainThread { my $idx = 0; foreach my $point (/$numRE/go) { - newCurve("", "", undef, $idx) unless exists $curves[$idx]; - - push @{$curves[$idx]}, [$xlast, $point]; + pushPoint($idx, [$xlast, $point]); $idx++; } } @@ -435,7 +439,7 @@ sub plotStoredData } } -sub newCurve() +sub newCurve { my ($title, $opts, $newpoint, $idx) = @_; @@ -479,3 +483,25 @@ sub pushNewEmptyCurve my $opts = "notitle "; push @curves, [{"options" => " $opts"}]; } + +sub pushPoint +{ + my ($idx, $xy) = @_; + + if ( !exists $curves[$idx] ) + { + newCurve("", "", undef, $idx); + } + elsif($options{monotonic}) + { + my $curve = $curves[$idx]; + if( @$curve > 1 && $xy->[0] < $curve->[$#{$curve}][0] ) + { + # the x-coordinate of the new point is in the past, so I wipe out all the data for this curve + # and start anew + splice( @$curve, 1, @$curve-1 ); + } + } + + push @{$curves[$idx]}, $xy; +} From 769592b814f2f0f5ee1a40c00636772753c81b7b Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 28 Mar 2010 19:18:17 -0700 Subject: [PATCH 071/270] fixed 0-vs-undef error in the plot bounds. 0 is now a valid value for a plot bound --- feedGnuplot.pl | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index a0b9bd2..1f75478 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -123,10 +123,6 @@ my %options = ( "stream" => 0, "points" => 0, "lines" => 0, "xlen" => 0, - "ymin" => "", - "ymax" => "", - "y2min" => "", - "y2max" => "", "maxcurves" => 100); GetOptions(\%options, @@ -262,15 +258,27 @@ sub mainThread { print PIPE "set terminal x11\n"; } + # If a bound isn't given I want to set it to the empty string, so I can communicate it simply to + # gnuplot + $options{xmin} = "" unless defined $options{xmin}; + $options{xmax} = "" unless defined $options{xmax}; + $options{ymin} = "" unless defined $options{ymin}; + $options{ymax} = "" unless defined $options{ymax}; + $options{y2min} = "" unless defined $options{y2min}; + $options{y2max} = "" unless defined $options{y2max}; + print PIPE "set xtics\n"; if($options{"y2"}) { print PIPE "set ytics nomirror\n"; print PIPE "set y2tics\n"; - print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if( $options{"y2min"} || $options{"y2max"} ); + # if any of the ranges are given, set the range + print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if length( $options{"y2min"} . $options{"y2max"} ); } - print PIPE "set xrange [". $options{"xmin"} . ":" . $options{"xmax"} ."]\n" if( $options{"xmin"} || $options{"xmax"} );; - print PIPE "set yrange [". $options{"ymin"} . ":" . $options{"ymax"} ."]\n" if( $options{"ymin"} || $options{"ymax"} );; + + # if any of the ranges are given, set the range + print PIPE "set xrange [". $options{"xmin"} . ":" . $options{"xmax"} ."]\n" if length( $options{"xmin"} . $options{"xmax"} ); + print PIPE "set yrange [". $options{"ymin"} . ":" . $options{"ymax"} ."]\n" if length( $options{"ymin"} . $options{"ymax"} ); print PIPE "set style data $style\n"; print PIPE "set grid\n"; From 7a7b22a5e6e0d22e35e1947fd6b50f83c2eb47e4 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 11 Apr 2010 13:33:04 -0700 Subject: [PATCH 072/270] added license --- LICENSE | 1 + 1 file changed, 1 insertion(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e58e70a --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +This script is released into the public domain. From df53ae9067d9a330b3bc3dc8b34d2631be7f0b6c Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 12 May 2010 02:30:51 -0700 Subject: [PATCH 073/270] larger png image output by default --- feedGnuplot.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 1f75478..4ae5e24 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -248,7 +248,7 @@ sub mainThread { my %terminalOpts = ( ps => 'postscript solid color landscape 10', pdf => 'pdfcairo solid color font ",10" size 11in,8.5in', - png => 'png' ); + png => 'png size 1280,1024' ); print PIPE "set terminal $terminalOpts{$outputfileType}\n"; print PIPE "set output \"$outputfile\"\n"; From 15b8bc7576494155b3500db372b2900cb6c426aa Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 12 May 2010 23:00:39 -0700 Subject: [PATCH 074/270] added gnuplot size option --- feedGnuplot.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 4ae5e24..795240b 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -86,6 +86,8 @@ As an example, if line 3 of the input is "0 9 1 20" --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed + --size xxx Gnuplot size option + --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename @@ -144,6 +146,7 @@ GetOptions(\%options, "y2min=f", "y2max=f", "y2=i@", + "size=s", "hardcopy=s", "maxcurves=i", "monotonic!", @@ -287,6 +290,8 @@ sub mainThread { print(PIPE "set y2label \"" . $options{"y2label"} . "\"\n") if $options{"y2label"}; print(PIPE "set title \"" . $options{"title" } . "\"\n") if $options{"title"}; + print(PIPE "set size \"" . $options{size} . "\"\n") if defined $options{"size"}; + # For the specified values, set the legend entries to 'title "blah blah"' if($options{"legend"}) { From 5444886acc0b9f7c0000c659295cf8e428af6b0a Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 28 May 2010 10:58:48 -0700 Subject: [PATCH 075/270] made the script compatible with perl 5.8 by no longer using the // operator --- feedGnuplot.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 795240b..fc47a01 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -317,7 +317,8 @@ sub mainThread { my $xlast; my $haveNewData; - while( $_ = ($dataQueue && $dataQueue->dequeue()) // <> ) + # I should be using the // operator, but I'd like to be compatible with perl 5.8 + while( $_ = (defined $dataQueue ? $dataQueue->dequeue() : <>)) { next if /^#/o; @@ -344,7 +345,9 @@ sub mainThread { # since $. is not meaningful in the plotting thread if we're using the data queue, we pass # $. on the data queue in that case. This construct pulls it from the queue if we're using # it, otherwise it uses $. directly - $xlast = ($dataQueue && $dataQueue->dequeue()) // $.; + + # I should be using the // operator, but I'd like to be compatible with perl 5.8 + $xlast = defined $dataQueue ? $dataQueue->dequeue() : $.; } if($options{dataindex}) From 9bac6563967038c557fc5821ce426586e7b64026 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 28 May 2010 13:19:01 -0700 Subject: [PATCH 076/270] the 'number' regexp is now case-insensitive --- feedGnuplot.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index fc47a01..6f83e9e 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -313,7 +313,7 @@ sub mainThread { } # regexp for a possibly floating point, possibly scientific notation number, fully captured - my $numRE = qr/([-]?[0-9\.]+(?:e[-+]?[0-9]+)?)/o; + my $numRE = qr/([-]?[0-9\.]+(?:e[-+]?[0-9]+)?)/io; my $xlast; my $haveNewData; From aed6f30b38100ba5d72978f485cb26a4dc6f8694 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Jun 2010 20:24:41 -0700 Subject: [PATCH 077/270] cleaned up the end-of-streaming logic --- feedGnuplot.pl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 6f83e9e..7a20505 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -6,6 +6,7 @@ use IO::Handle; use List::MoreUtils qw( first_index ); use Data::Dumper; use threads; +use threads::shared; use Thread::Queue; open(GNUPLOT_VERSION, "gnuplot --version |"); @@ -175,6 +176,7 @@ my @curves = (); my $dataQueue; my $xwindow; +my $streamingFinished : shared = undef; if($options{"stream"}) { if( defined $options{"hardcopy"}) @@ -199,11 +201,10 @@ if($options{"stream"}) } } - $dataQueue->enqueue("Plot now"); - $dataQueue->enqueue(undef); + $streamingFinished = 1; - $addThr->join(); $plotThr->join(); + $addThr->join(); } else { @@ -214,11 +215,14 @@ else sub plotThread { - while(1) + while(! $streamingFinished) { sleep(1); $dataQueue->enqueue("Plot now"); } + + $dataQueue->enqueue(undef); + } sub mainThread { From 613650c2342808209e3aaf1415683d0a5476fbb6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Jun 2010 21:38:59 -0700 Subject: [PATCH 078/270] fixed threading error where a plot command could be given between a line number and a data point --- feedGnuplot.pl | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 7a20505..81df6ec 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -190,15 +190,16 @@ if($options{"stream"}) while(<>) { - # place every line of input to the queue, so that the plotting thread can process it. - $dataQueue->enqueue($_); + chomp; - # if we are using an implicit domain (x = line number), then we send it on the data queue also, - # since $. is not meaningful in the plotting thread + # place every line of input to the queue, so that the plotting thread can process it. if we are + # using an implicit domain (x = line number), then we send it on the data queue also, since + # $. is not meaningful in the plotting thread if(!$options{domain}) { - $dataQueue->enqueue($.); + $_ .= " $."; } + $dataQueue->enqueue($_); } $streamingFinished = 1; @@ -347,11 +348,16 @@ sub mainThread { else { # since $. is not meaningful in the plotting thread if we're using the data queue, we pass - # $. on the data queue in that case. This construct pulls it from the queue if we're using - # it, otherwise it uses $. directly - - # I should be using the // operator, but I'd like to be compatible with perl 5.8 - $xlast = defined $dataQueue ? $dataQueue->dequeue() : $.; + # $. on the data queue in that case + if(defined $dataQueue) + { + s/ ([\d]+)$//o; + $xlast = $1; + } + else + { + $xlast = $.; + } } if($options{dataindex}) From 2d17b5b39436fb301a37c0be4df1d190a0eebb6f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Jun 2010 21:43:34 -0700 Subject: [PATCH 079/270] size option must not be quoted --- feedGnuplot.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 81df6ec..0f3b5a3 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -294,8 +294,7 @@ sub mainThread { print(PIPE "set ylabel \"" . $options{"ylabel" } . "\"\n") if $options{"ylabel"}; print(PIPE "set y2label \"" . $options{"y2label"} . "\"\n") if $options{"y2label"}; print(PIPE "set title \"" . $options{"title" } . "\"\n") if $options{"title"}; - - print(PIPE "set size \"" . $options{size} . "\"\n") if defined $options{"size"}; + print(PIPE "set size $options{size}\n") if $options{size}; # For the specified values, set the legend entries to 'title "blah blah"' if($options{"legend"}) From a86cd8c6210bab849a8cf00ea35187cb61827dda Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 6 Jun 2010 21:44:10 -0700 Subject: [PATCH 080/270] options should be set if they're defined, not if they're true necessarily --- feedGnuplot.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 0f3b5a3..1793bcb 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -290,11 +290,11 @@ sub mainThread { print PIPE "set style data $style\n"; print PIPE "set grid\n"; - print(PIPE "set xlabel \"" . $options{"xlabel" } . "\"\n") if $options{"xlabel"}; - print(PIPE "set ylabel \"" . $options{"ylabel" } . "\"\n") if $options{"ylabel"}; - print(PIPE "set y2label \"" . $options{"y2label"} . "\"\n") if $options{"y2label"}; - print(PIPE "set title \"" . $options{"title" } . "\"\n") if $options{"title"}; - print(PIPE "set size $options{size}\n") if $options{size}; + print(PIPE "set xlabel \"" . $options{"xlabel" } . "\"\n") if defined $options{"xlabel"}; + print(PIPE "set ylabel \"" . $options{"ylabel" } . "\"\n") if defined $options{"ylabel"}; + print(PIPE "set y2label \"" . $options{"y2label"} . "\"\n") if defined $options{"y2label"}; + print(PIPE "set title \"" . $options{"title" } . "\"\n") if defined $options{"title"}; + print(PIPE "set size $options{size}\n") if defined $options{size}; # For the specified values, set the legend entries to 'title "blah blah"' if($options{"legend"}) From 5f40f298d477f6b95e7b38465851f2fbadd02ccb Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 19 Jul 2010 12:32:15 -0700 Subject: [PATCH 081/270] added function to add options to single curves --- feedGnuplot.pl | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 1793bcb..48d7b91 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -305,15 +305,7 @@ sub mainThread { # For the values requested to be printed on the y2 axis, set that foreach my $y2idx (@{$options{"y2"}}) { - my $str = " axes x1y2 linewidth 3"; - if(exists $curves[$y2idx]) - { - $curves[$y2idx][0]{"options"} .= $str; - } - else - { - newCurve("", $str, undef, $y2idx); - } + addCurveOption($y2idx, 'axes x1y2 linewidth 3'); } # regexp for a possibly floating point, possibly scientific notation number, fully captured @@ -503,6 +495,19 @@ sub newCurve } } +sub addCurveOption +{ + my ($idx, $str) = @_; + if(exists $curves[$idx]) + { + $curves[$idx][0]{"options"} .= " $str"; + } + else + { + newCurve('', $str, undef, $idx); + } +} + sub pushNewEmptyCurve { my $opts = "notitle "; From 3a7933fe3f5f45cda885820f8bb7ef0d686151e1 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 19 Jul 2010 12:46:04 -0700 Subject: [PATCH 082/270] added cmdline options to add extra perl-plot styles and extra global commands --- feedGnuplot.pl | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 48d7b91..07e408f 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -87,6 +87,12 @@ As an example, if line 3 of the input is "0 9 1 20" --y2 xxx Plot the data with this index on the y2 axis. These are 0-indexed + --curvestyle xxx Additional style per curve. Give this option multiple + times for multiple curves + + --extracmds xxx Additional commands. These could contain extra global styles + for instance + --size xxx Gnuplot size option --hardcopy xxx If not streaming, output to a file specified here. Format @@ -147,6 +153,8 @@ GetOptions(\%options, "y2min=f", "y2max=f", "y2=i@", + "curvestyle=s@", + "extracmds=s@", "size=s", "hardcopy=s", "maxcurves=i", @@ -308,6 +316,26 @@ sub mainThread { addCurveOption($y2idx, 'axes x1y2 linewidth 3'); } +# add the extra curve options + if($options{"curvestyle"}) + { + my $idx = 0; + foreach (@{$options{"curvestyle"}}) + { + addCurveOption($idx, $_); + $idx++; + } + } + +# add the extra global options + if($options{"extracmds"}) + { + foreach (@{$options{"extracmds"}}) + { + print(PIPE "$_\n"); + } + } + # regexp for a possibly floating point, possibly scientific notation number, fully captured my $numRE = qr/([-]?[0-9\.]+(?:e[-+]?[0-9]+)?)/io; my $xlast; From 61b7eff596b641e2fd53543b5a8aa6ceedac0de8 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 22 Jul 2010 19:52:28 -0700 Subject: [PATCH 083/270] comment --- feedGnuplot.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 07e408f..3a37060 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -486,6 +486,10 @@ sub plotStoredData sub newCurve { + # I optionally pass in the title of this plot and any additional options separately. The title + # COULD be a part of $opts, but this raises an issue in the no-title case. When no title is + # specified, gnuplot will still add a legend entry with an unhelpful '-' label. I can still grep + # $opts to see if a title is given, but that's a bit ugly in its own way... my ($title, $opts, $newpoint, $idx) = @_; if(scalar @curves >= $options{maxcurves}) From 4155916053c4988bebadc125ad4ee6f3b4ba2bac Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 26 Jul 2010 02:29:45 -0700 Subject: [PATCH 084/270] added forgotten instance of quoting of the output filename --- feedGnuplot.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 3a37060..e4a50a2 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -434,7 +434,7 @@ sub mainThread { # 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 $outputfile; - usleep(100_000) until(system("fuser -s $outputfile")); + usleep(100_000) until(system("fuser -s \"$outputfile\"")); print "Wrote output to $outputfile\n"; return; From b45d476fe5e4029534cffc513714c76f57d98eaa Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 31 Jul 2010 21:39:40 -0700 Subject: [PATCH 085/270] spaced out commands in the README --- README | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README b/README index cb2d308..58923f2 100644 --- a/README +++ b/README @@ -6,9 +6,11 @@ plots from data coming in on STDIN or given in a filename passed on the commandline. Various data representations are supported, as is hardcopy output and streaming display of live data. A simple example: + seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot.pl --lines --points --legend "data 0" --title "Test plot" --y2 1 + You should see a plot with two curves (one on the y1 axis and the other on the y2 axis), a legend and a title. The first line of the example generates some data to plot and the second reads it in from STDIN and generates the @@ -20,9 +22,11 @@ By default, the line number of the incoming data is used for the x-axis. To plot an x-y dataset, feed in the x values as the first element in every line and pass in --domain. With the previous example: + seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot.pl --domain --lines --points --legend "data 0" --title "Test plot" --y2 1 + we get only one curve, with different x values. As many points as desired can appear on a single line, but all points on a line are associated with the X value that starts that line. @@ -32,9 +36,11 @@ plotted, this is undesireable. With the --dataindex option, each point in the input is preceded by an integer identifying the curve the point belongs to. With the previous example: + seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot.pl --dataindex --lines --points --legend "data 0" --title "Test plot" --y2 1 + we get 5 different curves with one point in each. The first column, as produced by awk, is '2,4,6,8,10'. These are interpreted as the indices of the curves to be plotted. The feedGnuplot.pl script created 11 different From 9212df053ade4f1422b9b427b8009a43529ee87f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 31 Jul 2010 21:46:32 -0700 Subject: [PATCH 086/270] added realtime plot example to the README --- README | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README b/README index 58923f2..68af0dd 100644 --- a/README +++ b/README @@ -64,7 +64,12 @@ windowsize-worth of data (windowsize has the units of the x axis, whether it is a point index or the passed-in domain). If --xlen is omitted or set to 0, all of the available data is plotted, with no moving window. The realtime data is updated at 1 Hz, so the script can handle rapidly-incoming data without -spending all of its time replotting. +spending all of its time replotting. Example: + + +seq 5 | awk '{print 2*$1, $1*$1; system("sleep 2"); fflush()}' | +feedGnuplot.pl --stream --lines --points --legend "data 0" --title "Test plot" --y2 1 + For more information, invoke with --help, or read the source. From e05c0e3232810963d4c3ba8db598c1077bcbb37f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 31 Jul 2010 23:54:52 -0700 Subject: [PATCH 087/270] more intelligent handling of shebang plotting --- feedGnuplot.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index e4a50a2..1a722af 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -8,6 +8,7 @@ use Data::Dumper; use threads; use threads::shared; use Thread::Queue; +use Text::ParseWords; open(GNUPLOT_VERSION, "gnuplot --version |"); my ($gnuplotVersion) = =~ /gnuplot\s*([0-9]*\.[0-9]*)/; @@ -120,7 +121,7 @@ OEF # takes care of both those cases. if(exists $ARGV[0] && !-r $ARGV[0]) { - unshift @ARGV, split(/\s+/, shift(@ARGV)); + unshift @ARGV, shellwords shift @ARGV; } # do not stream in the data by default From 593e1c09b9f8e82bfc76db7cb14a612fb6b3dbfd Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 1 Aug 2010 00:01:09 -0700 Subject: [PATCH 088/270] README now mentions self-plotting data files --- README | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/README b/README index 68af0dd..450e1bc 100644 --- a/README +++ b/README @@ -67,11 +67,44 @@ is updated at 1 Hz, so the script can handle rapidly-incoming data without spending all of its time replotting. Example: -seq 5 | awk '{print 2*$1, $1*$1; system("sleep 2"); fflush()}' | +seq 500 | awk '{print 2*$1, $1*$1; system("sleep 2"); fflush()}' | feedGnuplot.pl --stream --lines --points --legend "data 0" --title "Test plot" --y2 1 -For more information, invoke with --help, or read the source. +This script can be used to generate self-plotting data files. If a file +called 'data' is created with: + + +#!/usr/local/bin/feedGnuplot.pl --lines --points --legend "data 0" --title "Test plot" --y2 1 +2 1 +4 4 +6 9 +8 16 +10 25 +12 36 +14 49 +16 64 +18 81 +20 100 +22 121 +24 144 +26 169 +28 196 +30 225 + + +This file can be plotted with + + +bash$ ./tst + + +The caveats here are that on Linux the whole #! line is limited to 127 +charaters and that the full path to feedGnuplot.pl must be given. + +For more information, invoke with --help, or read the source. Any bugs or +suggestions should be addressed to dkogan@cds.caltech.edu. The latest +version of the script is available at http://github.com/dkogan/feedgnuplot This program is originally based on the driveGnuPlots.pl script from From d1ec685694aff1c0fa87b47fb2ea4775dacf1ea7 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 15 Sep 2010 21:55:44 -0700 Subject: [PATCH 089/270] I now check for defined-ness of the legend instead of its truth. As a result I can now have a '0' legend --- feedGnuplot.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 1a722af..91902a9 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -515,8 +515,8 @@ sub newCurve $idx = $#curves; } - if($title) { $opts = "title \"$title\" $opts" } - else { $opts = "notitle $opts" } + if(defined $title) { $opts = "title \"$title\" $opts" } + else { $opts = "notitle $opts" } if( defined $newpoint ) { From 869fba996ded6cbf91f5c64f141a0f9213420b1c Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 18 Oct 2010 13:03:38 -0700 Subject: [PATCH 090/270] added option to plot with a square aspect ratio --- feedGnuplot.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 91902a9..1d95747 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -96,6 +96,8 @@ As an example, if line 3 of the input is "0 9 1 20" --size xxx Gnuplot size option + --square Plot data with aspect ratio 1 + --hardcopy xxx If not streaming, output to a file specified here. Format inferred from filename @@ -157,6 +159,7 @@ GetOptions(\%options, "curvestyle=s@", "extracmds=s@", "size=s", + "square!", "hardcopy=s", "maxcurves=i", "monotonic!", @@ -303,6 +306,12 @@ sub mainThread { print(PIPE "set ylabel \"" . $options{"ylabel" } . "\"\n") if defined $options{"ylabel"}; print(PIPE "set y2label \"" . $options{"y2label"} . "\"\n") if defined $options{"y2label"}; print(PIPE "set title \"" . $options{"title" } . "\"\n") if defined $options{"title"}; + + if($options{square}) + { + $options{size} = '' unless defined $options{size}; + $options{size} .= " ratio -1"; + } print(PIPE "set size $options{size}\n") if defined $options{size}; # For the specified values, set the legend entries to 'title "blah blah"' From e4f3122d3f5c07003ea58028dab8422c206d8bc6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 18 Oct 2010 13:44:33 -0700 Subject: [PATCH 091/270] better sensing of "new data" --- feedGnuplot.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 1d95747..0bfb0d9 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -358,8 +358,6 @@ sub mainThread { if($_ ne "Plot now") { - $haveNewData = 1; - # parse the incoming data lines. The format is # x idx0 dat0 idx1 dat1 .... # where idxX is the index of the curve that datX corresponds to @@ -396,6 +394,7 @@ sub mainThread { my $idx = $1; my $point = $2; + $haveNewData = 1; pushPoint($idx, [$xlast, $point]); } } @@ -404,6 +403,7 @@ sub mainThread { my $idx = 0; foreach my $point (/$numRE/go) { + $haveNewData = 1; pushPoint($idx, [$xlast, $point]); $idx++; } From 139f89e145ebb7b38bfa72596a33ebaaa9c9974b Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 23 Sep 2010 23:02:35 -0700 Subject: [PATCH 092/270] minor streamlining --- feedGnuplot.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 0bfb0d9..4516d27 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -486,9 +486,9 @@ sub plotStoredData { # send each point to gnuplot. Ignore the first "point" since it's the # curve options - for my $elem (@{$buf}[1..$#$buf]) { - my ($x, $y) = @$elem; - print PIPE "$x $y\n"; + for my $elem (@{$buf}[1..$#$buf]) + { + print PIPE "@$elem\n"; } print PIPE "e\n"; } From 254cdaf6a8cc123a6113eb3d609b748bda7076c9 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 28 Sep 2010 23:04:33 -0700 Subject: [PATCH 093/270] no longer importing functions I'm not using --- feedGnuplot.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 4516d27..9224fb8 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl -w use strict; use Getopt::Long; -use Time::HiRes qw( usleep gettimeofday tv_interval); +use Time::HiRes qw( usleep ); use IO::Handle; use List::MoreUtils qw( first_index ); use Data::Dumper; From 9c1d6326d858be987c611cfae26f49b3ec22d808 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 28 Sep 2010 23:05:17 -0700 Subject: [PATCH 094/270] renamed a function --- feedGnuplot.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 9224fb8..35b1d56 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -418,7 +418,7 @@ sub mainThread { if( $options{"xlen"} ) { - cutOld($xlast - $options{"xlen"}); + pruneOldData($xlast - $options{"xlen"}); plotStoredData($xlast - $options{"xlen"}, $xlast); } else @@ -457,7 +457,7 @@ sub mainThread { } } -sub cutOld +sub pruneOldData { my ($oldestx) = @_; From cbba09917b913eee6aa10d74fdb2141026f31a56 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 00:28:14 -0700 Subject: [PATCH 095/270] now using \d to match digits --- feedGnuplot.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 35b1d56..a61ebda 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -11,7 +11,7 @@ use Thread::Queue; use Text::ParseWords; open(GNUPLOT_VERSION, "gnuplot --version |"); -my ($gnuplotVersion) = =~ /gnuplot\s*([0-9]*\.[0-9]*)/; +my ($gnuplotVersion) = =~ /gnuplot\s*(\d*\.\d*)/; if(!$gnuplotVersion) { print STDERR "Couldn't find the version of gnuplot. Does it work? Trying anyway...\n"; @@ -347,7 +347,7 @@ sub mainThread { } # regexp for a possibly floating point, possibly scientific notation number, fully captured - my $numRE = qr/([-]?[0-9\.]+(?:e[-+]?[0-9]+)?)/io; + my $numRE = qr/([-]?[\d\.]+(?:e[-+]?\d+)?)/io; my $xlast; my $haveNewData; @@ -389,7 +389,7 @@ sub mainThread { if($options{dataindex}) { - while(/([0-9]+)\s+$numRE/go) + while(/(\d+)\s+$numRE/go) { my $idx = $1; my $point = $2; From 78bb507f36c681fa24bef48f51b2bf45faa71d2c Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 00:50:32 -0700 Subject: [PATCH 096/270] made pushNewEmptyCurve() a local subroutine of the subroutine that uses it --- feedGnuplot.pl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index a61ebda..a6f3ac5 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -496,6 +496,12 @@ sub plotStoredData sub newCurve { + sub pushNewEmptyCurve + { + my $opts = "notitle "; + push @curves, [{"options" => " $opts"}]; + } + # I optionally pass in the title of this plot and any additional options separately. The title # COULD be a part of $opts, but this raises an issue in the no-title case. When no title is # specified, gnuplot will still add a legend entry with an unhelpful '-' label. I can still grep @@ -550,12 +556,7 @@ sub addCurveOption } } -sub pushNewEmptyCurve -{ - my $opts = "notitle "; - push @curves, [{"options" => " $opts"}]; -} - +# function to add a point to the plot. Assumes that the curve indexed by $idx already exists sub pushPoint { my ($idx, $xy) = @_; From f5ee508d257926dc9bb65713d6a50765750fdf4f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 01:08:52 -0700 Subject: [PATCH 097/270] I no longer add any data points in the newCurve() call, so I remove newCurve() 's ability to do that --- feedGnuplot.pl | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index a6f3ac5..794c4e6 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -506,7 +506,7 @@ sub newCurve # COULD be a part of $opts, but this raises an issue in the no-title case. When no title is # specified, gnuplot will still add a legend entry with an unhelpful '-' label. I can still grep # $opts to see if a title is given, but that's a bit ugly in its own way... - my ($title, $opts, $newpoint, $idx) = @_; + my ($title, $opts, $idx) = @_; if(scalar @curves >= $options{maxcurves}) { @@ -533,14 +533,7 @@ sub newCurve if(defined $title) { $opts = "title \"$title\" $opts" } else { $opts = "notitle $opts" } - if( defined $newpoint ) - { - $curves[$idx] = [{"options" => " $opts"}, $newpoint]; - } - else - { - $curves[$idx] = [{"options" => " $opts"}]; - } + $curves[$idx] = [{"options" => " $opts"}]; } sub addCurveOption @@ -552,7 +545,7 @@ sub addCurveOption } else { - newCurve('', $str, undef, $idx); + newCurve('', $str, $idx); } } @@ -563,7 +556,7 @@ sub pushPoint if ( !exists $curves[$idx] ) { - newCurve("", "", undef, $idx); + newCurve("", "", $idx); } elsif($options{monotonic}) { From 1e729e3b06f06d26d0f25f66c1fe19e626ab3a65 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 01:15:42 -0700 Subject: [PATCH 098/270] say -> print for perl 5.8 compatibility --- feedGnuplot.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 794c4e6..17b7f01 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -510,8 +510,8 @@ sub newCurve if(scalar @curves >= $options{maxcurves}) { - say STDERR "Tried to exceed the --maxcurves setting."; - say STDERR "Invoke with a higher --maxcurves limit if you really want to do this."; + print STDERR "Tried to exceed the --maxcurves setting.\n"; + print STDERR "Invoke with a higher --maxcurves limit if you really want to do this.\n"; return; } From c11f8df99bee7c96c8b1bec40cf73a003a0c0f95 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 14:40:11 -0700 Subject: [PATCH 099/270] the --dataindex option has been changed to --dataid, with alphanumeric IDs. This necessiatated some cleanup --- feedGnuplot.pl | 157 +++++++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 77 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 17b7f01..df96f20 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -29,25 +29,26 @@ Usage: $0 [options] file1 file2 ... --[no]domain If enabled, the first element of each line is the domain variable. If not, the point index is used - --[no]dataindex If enabled, each data point is preceded by the index - of the data set that point corresponds to. If not + --[no]dataid If enabled, each data point is preceded by the ID + of the data set that point corresponds to. This ID is + interpreted as a string, NOT as just a number. If not enabled, the order of the point is used. As an example, if line 3 of the input is "0 9 1 20" - '--nodomain --nodataindex' would parse the 4 numbers as points in 4 + '--nodomain --nodataid' would parse the 4 numbers as points in 4 different curves at x=3 - '--domain --nodataindex' would parse the 4 numbers as points in 3 different + '--domain --nodataid' would parse the 4 numbers as points in 3 different curves at x=0. Here, 0 is the x-variable and 9,1,20 are the data values - '--nodomain --dataindex' would parse the 4 numbers as points in 2 different - curves at x=3. Here 0 and 1 are the data indices and 9 and 20 are the + '--nodomain --dataid' would parse the 4 numbers as points in 2 different + curves at x=3. Here 0 and 1 are the data IDs and 9 and 20 are the data values - '--domain --dataindex' would parse the 4 numbers as a single point at - x=0. Here 9 is the data index and 1 is the data value. 20 is an extra + '--domain --dataid' would parse the 4 numbers as a single point at + x=0. Here 9 is the data ID and 1 is the data value. 20 is an extra value, so it is ignored. If another value followed 20, we'd get another - point in curve number + point in curve ID 20 --[no]stream Do [not] display the data a point at a time, as it @@ -85,8 +86,8 @@ As an example, if line 3 of the input is "0 9 1 20" --y2max xxx Set the range for the y2 axis. - --y2 xxx Plot the data with this index on the y2 axis. These are - 0-indexed + --y2 xxx Plot the data specified by this curve ID on the y2 axis. + Without --dataid, the ID is just an ordered 0-based index --curvestyle xxx Additional style per curve. Give this option multiple times for multiple curves @@ -131,7 +132,7 @@ if(exists $ARGV[0] && !-r $ARGV[0]) # no monotonicity checks by default my %options = ( "stream" => 0, "domain" => 0, - "dataindex" => 0, + "dataid" => 0, "points" => 0, "lines" => 0, "xlen" => 0, @@ -140,7 +141,7 @@ my %options = ( "stream" => 0, GetOptions(\%options, "stream!", "domain!", - "dataindex!", + "dataid!", "lines!", "points!", "legend=s@", @@ -155,7 +156,7 @@ GetOptions(\%options, "xmax=f", "y2min=f", "y2max=f", - "y2=i@", + "y2=s@", "curvestyle=s@", "extracmds=s@", "size=s", @@ -184,6 +185,9 @@ if( defined $options{"help"} ) # references to lists of (x,y) tuples my @curves = (); +# list mapping curve names to their indices in the @curves list +my %curveIndices = (); + # now start the data acquisition and plotting threads my $dataQueue; my $xwindow; @@ -317,26 +321,29 @@ sub mainThread { # For the specified values, set the legend entries to 'title "blah blah"' if($options{"legend"}) { - foreach (@{$options{"legend"}}) { newCurve($_, "") } - } - -# For the values requested to be printed on the y2 axis, set that - foreach my $y2idx (@{$options{"y2"}}) - { - addCurveOption($y2idx, 'axes x1y2 linewidth 3'); + my $id = 0; + foreach (@{$options{"legend"}}) + { + setCurveLabel($id++, $_); + } } # add the extra curve options if($options{"curvestyle"}) { - my $idx = 0; + my $id = 0; foreach (@{$options{"curvestyle"}}) { - addCurveOption($idx, $_); - $idx++; + addCurveOption($id++, $_); } } +# For the values requested to be printed on the y2 axis, set that + foreach (@{$options{"y2"}}) + { + addCurveOption($_, 'axes x1y2 linewidth 3'); + } + # add the extra global options if($options{"extracmds"}) { @@ -359,12 +366,12 @@ sub mainThread { if($_ ne "Plot now") { # parse the incoming data lines. The format is - # x idx0 dat0 idx1 dat1 .... - # where idxX is the index of the curve that datX corresponds to + # x id0 dat0 id1 dat1 .... + # where idX is the ID of the curve that datX corresponds to # # $options{domain} indicates whether the initial 'x' is given or not (if not, the line # number is used) - # $options{dataindex} indicates whether idxX is given or not (if not, the point order in the + # $options{dataid} indicates whether idX is given or not (if not, the point order in the # line is used) if($options{domain}) @@ -387,25 +394,25 @@ sub mainThread { } } - if($options{dataindex}) + if($options{dataid}) { - while(/(\d+)\s+$numRE/go) + while(/(\w+)\s+$numRE/go) { - my $idx = $1; my $point = $2; $haveNewData = 1; - pushPoint($idx, [$xlast, $point]); + pushPoint(getCurveIdx($1), + [$xlast, $point]); } } else { - my $idx = 0; + my $id = 0; foreach my $point (/$numRE/go) { $haveNewData = 1; - pushPoint($idx, [$xlast, $point]); - $idx++; + pushPoint(getCurveIdx($id++), + [$xlast, $point]); } } } @@ -494,59 +501,59 @@ sub plotStoredData } } -sub newCurve +sub updateCurveOptions { - sub pushNewEmptyCurve - { - my $opts = "notitle "; - push @curves, [{"options" => " $opts"}]; - } + # generates the "options" string for a curve, based on its legend title and its other options + # These could be integrated into a single string, but that raises an issue in the no-title + # case. When no title is specified, gnuplot will still add a legend entry with an unhelpful '-' + # label. Thus I explicitly do "notitle" for that case - # I optionally pass in the title of this plot and any additional options separately. The title - # COULD be a part of $opts, but this raises an issue in the no-title case. When no title is - # specified, gnuplot will still add a legend entry with an unhelpful '-' label. I can still grep - # $opts to see if a title is given, but that's a bit ugly in its own way... - my ($title, $opts, $idx) = @_; + my ($curveoptions) = @_; + my $titleoption = defined $curveoptions->{title} ? + "title \"$curveoptions->{title}\"" : "notitle"; + + $curveoptions->{options} = "$curveoptions->{extraoptions} $titleoption"; +} + +sub getCurveIdx +{ + # This function returns the curve index for a particular curve, creating a new curve if necessary if(scalar @curves >= $options{maxcurves}) { print STDERR "Tried to exceed the --maxcurves setting.\n"; print STDERR "Invoke with a higher --maxcurves limit if you really want to do this.\n"; - return; + exit; } - # if this curve index doesn't exist, create curve up-to this index - if(defined $idx) + my ($id) = @_; + + if( !exists $curveIndices{$id} ) { - while(!exists $curves[$idx]) - { - pushNewEmptyCurve(); - } - } - else - { - # if we're not given an index, create a new one at the end, and fill it in - pushNewEmptyCurve(); - $idx = $#curves; - } + push @curves, [{extraoptions => ' '}]; # push a curve with no data and no options + $curveIndices{$id} = $#curves; - if(defined $title) { $opts = "title \"$title\" $opts" } - else { $opts = "notitle $opts" } - - $curves[$idx] = [{"options" => " $opts"}]; + updateCurveOptions($curves[$#curves][0]); + } + return $curveIndices{$id}; } sub addCurveOption { - my ($idx, $str) = @_; - if(exists $curves[$idx]) - { - $curves[$idx][0]{"options"} .= " $str"; - } - else - { - newCurve('', $str, $idx); - } + my ($id, $str) = @_; + + my $idx = getCurveIdx($id); + $curves[$idx][0]{extraoptions} .= "$str "; + updateCurveOptions($curves[$idx][0]); +} + +sub setCurveLabel +{ + my ($id, $str) = @_; + + my $idx = getCurveIdx($id); + $curves[$idx][0]{title} = $str; + updateCurveOptions($curves[$idx][0]); } # function to add a point to the plot. Assumes that the curve indexed by $idx already exists @@ -554,11 +561,7 @@ sub pushPoint { my ($idx, $xy) = @_; - if ( !exists $curves[$idx] ) - { - newCurve("", "", $idx); - } - elsif($options{monotonic}) + if($options{monotonic}) { my $curve = $curves[$idx]; if( @$curve > 1 && $xy->[0] < $curve->[$#{$curve}][0] ) From 61a1b2c2b8a5bac5c3f496c4f52ac0ecb81b356a Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 14:44:55 -0700 Subject: [PATCH 100/270] getCurveIdx() has been replaced with getCurve(). I now return the curve data itself, not the index to it --- feedGnuplot.pl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index df96f20..7c4a7a0 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -401,7 +401,7 @@ sub mainThread { my $point = $2; $haveNewData = 1; - pushPoint(getCurveIdx($1), + pushPoint(getCurve($1), [$xlast, $point]); } } @@ -411,7 +411,7 @@ sub mainThread { foreach my $point (/$numRE/go) { $haveNewData = 1; - pushPoint(getCurveIdx($id++), + pushPoint(getCurve($id++), [$xlast, $point]); } } @@ -515,9 +515,10 @@ sub updateCurveOptions $curveoptions->{options} = "$curveoptions->{extraoptions} $titleoption"; } -sub getCurveIdx +sub getCurve { - # This function returns the curve index for a particular curve, creating a new curve if necessary + # This function returns the curve corresponding to a particular label, creating a new curve if + # necessary if(scalar @curves >= $options{maxcurves}) { @@ -535,35 +536,34 @@ sub getCurveIdx updateCurveOptions($curves[$#curves][0]); } - return $curveIndices{$id}; + return $curves[$curveIndices{$id}]; } sub addCurveOption { my ($id, $str) = @_; - my $idx = getCurveIdx($id); - $curves[$idx][0]{extraoptions} .= "$str "; - updateCurveOptions($curves[$idx][0]); + my $curve = getCurve($id); + $curve->[0]{extraoptions} .= "$str "; + updateCurveOptions($curve->[0]); } sub setCurveLabel { my ($id, $str) = @_; - my $idx = getCurveIdx($id); - $curves[$idx][0]{title} = $str; - updateCurveOptions($curves[$idx][0]); + my $curve = getCurve($id); + $curve->[0]{title} = $str; + updateCurveOptions($curve->[0]); } # function to add a point to the plot. Assumes that the curve indexed by $idx already exists sub pushPoint { - my ($idx, $xy) = @_; + my ($curve, $xy) = @_; if($options{monotonic}) { - my $curve = $curves[$idx]; if( @$curve > 1 && $xy->[0] < $curve->[$#{$curve}][0] ) { # the x-coordinate of the new point is in the past, so I wipe out all the data for this curve @@ -572,5 +572,5 @@ sub pushPoint } } - push @{$curves[$idx]}, $xy; + push @$curve, $xy; } From ea795e36eb00b7478701b55eb4edc7228a35f6c6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 14:45:58 -0700 Subject: [PATCH 101/270] no longer using Data::Dumper by default --- feedGnuplot.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 7c4a7a0..4127492 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -4,7 +4,6 @@ use Getopt::Long; use Time::HiRes qw( usleep ); use IO::Handle; use List::MoreUtils qw( first_index ); -use Data::Dumper; use threads; use threads::shared; use Thread::Queue; From 8135ab0a2d112747fd85ed0687cca791d36053f5 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 14:49:42 -0700 Subject: [PATCH 102/270] don't need quotes when looking up hashes --- feedGnuplot.pl | 64 +++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 4127492..120a9d7 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -168,12 +168,12 @@ GetOptions(\%options, # set up plotting style my $style = ""; -if($options{"lines"}) { $style .= "lines";} -if($options{"points"}) { $style .= "points";} +if($options{lines}) { $style .= "lines";} +if($options{points}) { $style .= "points";} if(!$style) { $style = "points"; } -if( defined $options{"help"} ) +if( defined $options{help} ) { die($usage); } @@ -192,11 +192,11 @@ my $dataQueue; my $xwindow; my $streamingFinished : shared = undef; -if($options{"stream"}) +if($options{stream}) { - if( defined $options{"hardcopy"}) + if( defined $options{hardcopy}) { - $options{"stream"} = undef; + $options{stream} = undef; } $dataQueue = Thread::Queue->new(); @@ -247,10 +247,10 @@ sub mainThread { if($gnuplotVersion >= 4.3) { - $dopersist = "--persist" if(!$options{"stream"}); + $dopersist = "--persist" if(!$options{stream}); } - if(exists $options{"dump"}) + if(exists $options{dump}) { *PIPE = *STDOUT; } @@ -262,9 +262,9 @@ sub mainThread { my $outputfile; my $outputfileType; - if( defined $options{"hardcopy"}) + if( defined $options{hardcopy}) { - $outputfile = $options{"hardcopy"}; + $outputfile = $options{hardcopy}; ($outputfileType) = $outputfile =~ /\.(ps|pdf|png)$/; if(!$outputfileType) { die("Only .ps, .pdf and .png supported\n"); } @@ -291,24 +291,24 @@ sub mainThread { $options{y2max} = "" unless defined $options{y2max}; print PIPE "set xtics\n"; - if($options{"y2"}) + if($options{y2}) { print PIPE "set ytics nomirror\n"; print PIPE "set y2tics\n"; # if any of the ranges are given, set the range - print PIPE "set y2range [". $options{"y2min"} . ":" . $options{"y2max"} ."]\n" if length( $options{"y2min"} . $options{"y2max"} ); + print PIPE "set y2range [". $options{y2min} . ":" . $options{y2max} ."]\n" if length( $options{y2min} . $options{y2max} ); } # if any of the ranges are given, set the range - print PIPE "set xrange [". $options{"xmin"} . ":" . $options{"xmax"} ."]\n" if length( $options{"xmin"} . $options{"xmax"} ); - print PIPE "set yrange [". $options{"ymin"} . ":" . $options{"ymax"} ."]\n" if length( $options{"ymin"} . $options{"ymax"} ); + print PIPE "set xrange [". $options{xmin} . ":" . $options{xmax} ."]\n" if length( $options{xmin} . $options{xmax} ); + print PIPE "set yrange [". $options{ymin} . ":" . $options{ymax} ."]\n" if length( $options{ymin} . $options{ymax} ); print PIPE "set style data $style\n"; print PIPE "set grid\n"; - print(PIPE "set xlabel \"" . $options{"xlabel" } . "\"\n") if defined $options{"xlabel"}; - print(PIPE "set ylabel \"" . $options{"ylabel" } . "\"\n") if defined $options{"ylabel"}; - print(PIPE "set y2label \"" . $options{"y2label"} . "\"\n") if defined $options{"y2label"}; - print(PIPE "set title \"" . $options{"title" } . "\"\n") if defined $options{"title"}; + print(PIPE "set xlabel \"" . $options{xlabel } . "\"\n") if defined $options{xlabel}; + print(PIPE "set ylabel \"" . $options{ylabel } . "\"\n") if defined $options{ylabel}; + print(PIPE "set y2label \"" . $options{y2label} . "\"\n") if defined $options{y2label}; + print(PIPE "set title \"" . $options{title } . "\"\n") if defined $options{title}; if($options{square}) { @@ -318,35 +318,35 @@ sub mainThread { print(PIPE "set size $options{size}\n") if defined $options{size}; # For the specified values, set the legend entries to 'title "blah blah"' - if($options{"legend"}) + if($options{legend}) { my $id = 0; - foreach (@{$options{"legend"}}) + foreach (@{$options{legend}}) { setCurveLabel($id++, $_); } } # add the extra curve options - if($options{"curvestyle"}) + if($options{curvestyle}) { my $id = 0; - foreach (@{$options{"curvestyle"}}) + foreach (@{$options{curvestyle}}) { addCurveOption($id++, $_); } } # For the values requested to be printed on the y2 axis, set that - foreach (@{$options{"y2"}}) + foreach (@{$options{y2}}) { addCurveOption($_, 'axes x1y2 linewidth 3'); } # add the extra global options - if($options{"extracmds"}) + if($options{extracmds}) { - foreach (@{$options{"extracmds"}}) + foreach (@{$options{extracmds}}) { print(PIPE "$_\n"); } @@ -416,16 +416,16 @@ sub mainThread { } } - elsif($options{"stream"}) + elsif($options{stream}) { # only redraw a streaming plot if there's new data to plot next unless $haveNewData; $haveNewData = undef; - if( $options{"xlen"} ) + if( $options{xlen} ) { - pruneOldData($xlast - $options{"xlen"}); - plotStoredData($xlast - $options{"xlen"}, $xlast); + pruneOldData($xlast - $options{xlen}); + plotStoredData($xlast - $options{xlen}, $xlast); } else { @@ -435,7 +435,7 @@ sub mainThread { } # finished reading in all of the data - if($options{"stream"}) + if($options{stream}) { print PIPE "exit;\n"; close PIPE; @@ -444,7 +444,7 @@ sub mainThread { { plotStoredData(); - if( defined $options{"hardcopy"}) + if( defined $options{hardcopy}) { print PIPE "set output\n"; # sleep until the plot file exists, and it is closed. Sometimes the output is @@ -484,7 +484,7 @@ sub plotStoredData # get the options for those curves that have any data my @nonemptyCurves = grep {@$_ > 1} @curves; - my @extraopts = map {$_->[0]{"options"}} @nonemptyCurves; + my @extraopts = map {$_->[0]{options}} @nonemptyCurves; print PIPE 'plot ' . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; From 4dfb086e965b54b052d05cfd2189ff3e0720f0eb Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 15:42:08 -0700 Subject: [PATCH 103/270] using ' instead of " for most of the strings that don't require interpolation --- feedGnuplot.pl | 106 ++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 120a9d7..22c23c7 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -9,7 +9,7 @@ use threads::shared; use Thread::Queue; use Text::ParseWords; -open(GNUPLOT_VERSION, "gnuplot --version |"); +open(GNUPLOT_VERSION, 'gnuplot --version |'); my ($gnuplotVersion) = =~ /gnuplot\s*(\d*\.\d*)/; if(!$gnuplotVersion) { @@ -129,49 +129,49 @@ if(exists $ARGV[0] && !-r $ARGV[0]) # do not stream in the data by default # point plotting by default. # no monotonicity checks by default -my %options = ( "stream" => 0, - "domain" => 0, - "dataid" => 0, - "points" => 0, - "lines" => 0, - "xlen" => 0, - "maxcurves" => 100); +my %options = ( stream => 0, + domain => 0, + dataid => 0, + points => 0, + lines => 0, + xlen => 0, + maxcurves => 100); GetOptions(\%options, - "stream!", - "domain!", - "dataid!", - "lines!", - "points!", - "legend=s@", - "xlabel=s", - "ylabel=s", - "y2label=s", - "title=s", - "xlen=f", - "ymin=f", - "ymax=f", - "xmin=f", - "xmax=f", - "y2min=f", - "y2max=f", - "y2=s@", - "curvestyle=s@", - "extracmds=s@", - "size=s", - "square!", - "hardcopy=s", - "maxcurves=i", - "monotonic!", - "help", - "dump") or die($usage); + 'stream!', + 'domain!', + 'dataid!', + 'lines!', + 'points!', + 'legend=s@', + 'xlabel=s', + 'ylabel=s', + 'y2label=s', + 'title=s', + 'xlen=f', + 'ymin=f', + 'ymax=f', + 'xmin=f', + 'xmax=f', + 'y2min=f', + 'y2max=f', + 'y2=s@', + 'curvestyle=s@', + 'extracmds=s@', + 'size=s', + 'square!', + 'hardcopy=s', + 'maxcurves=i', + 'monotonic!', + 'help', + 'dump') or die($usage); # set up plotting style -my $style = ""; -if($options{lines}) { $style .= "lines";} -if($options{points}) { $style .= "points";} +my $style = ''; +if($options{lines}) { $style .= 'lines';} +if($options{points}) { $style .= 'points';} -if(!$style) { $style = "points"; } +if(!$style) { $style = 'points'; } if( defined $options{help} ) { @@ -180,7 +180,7 @@ if( defined $options{help} ) # list containing the plot data. Each element is a reference to a list, representing the data for -# one curve. The first "point" is a hash describing various curve parameters. The rest are all +# one curve. The first 'point' is a hash describing various curve parameters. The rest are all # references to lists of (x,y) tuples my @curves = (); @@ -234,7 +234,7 @@ sub plotThread while(! $streamingFinished) { sleep(1); - $dataQueue->enqueue("Plot now"); + $dataQueue->enqueue('Plot now'); } $dataQueue->enqueue(undef); @@ -243,11 +243,11 @@ sub plotThread sub mainThread { local *PIPE; - my $dopersist = ""; + my $dopersist = ''; if($gnuplotVersion >= 4.3) { - $dopersist = "--persist" if(!$options{stream}); + $dopersist = '--persist' if(!$options{stream}); } if(exists $options{dump}) @@ -283,12 +283,12 @@ sub mainThread { # If a bound isn't given I want to set it to the empty string, so I can communicate it simply to # gnuplot - $options{xmin} = "" unless defined $options{xmin}; - $options{xmax} = "" unless defined $options{xmax}; - $options{ymin} = "" unless defined $options{ymin}; - $options{ymax} = "" unless defined $options{ymax}; - $options{y2min} = "" unless defined $options{y2min}; - $options{y2max} = "" unless defined $options{y2max}; + $options{xmin} = '' unless defined $options{xmin}; + $options{xmax} = '' unless defined $options{xmax}; + $options{ymin} = '' unless defined $options{ymin}; + $options{ymax} = '' unless defined $options{ymax}; + $options{y2min} = '' unless defined $options{y2min}; + $options{y2max} = '' unless defined $options{y2max}; print PIPE "set xtics\n"; if($options{y2}) @@ -313,7 +313,7 @@ sub mainThread { if($options{square}) { $options{size} = '' unless defined $options{size}; - $options{size} .= " ratio -1"; + $options{size} .= ' ratio -1'; } print(PIPE "set size $options{size}\n") if defined $options{size}; @@ -362,7 +362,7 @@ sub mainThread { { next if /^#/o; - if($_ ne "Plot now") + if($_ ne 'Plot now') { # parse the incoming data lines. The format is # x id0 dat0 id1 dat1 .... @@ -502,10 +502,10 @@ sub plotStoredData sub updateCurveOptions { - # generates the "options" string for a curve, based on its legend title and its other options + # generates the 'options' string for a curve, based on its legend title and its other options # These could be integrated into a single string, but that raises an issue in the no-title # case. When no title is specified, gnuplot will still add a legend entry with an unhelpful '-' - # label. Thus I explicitly do "notitle" for that case + # label. Thus I explicitly do 'notitle' for that case my ($curveoptions) = @_; my $titleoption = defined $curveoptions->{title} ? From 54fc148ed06856eaa7b9ad058a6a125be125bd58 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 17:08:29 -0700 Subject: [PATCH 104/270] added --autolegend option to generate the legends from curve IDs --- feedGnuplot.pl | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 22c23c7..5c5cdd3 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -68,6 +68,8 @@ As an example, if line 3 of the input is "0 9 1 20" --legend xxx Set the label for a curve plot. Give this option multiple times for multiple curves + --autolegend Use the curve IDs for the legend + --xlen xxx Set the size of the x-window to plot. Omit this or set it to 0 to plot ALL the data @@ -144,6 +146,7 @@ GetOptions(\%options, 'lines!', 'points!', 'legend=s@', + 'autolegend!', 'xlabel=s', 'ylabel=s', 'y2label=s', @@ -507,10 +510,13 @@ sub updateCurveOptions # case. When no title is specified, gnuplot will still add a legend entry with an unhelpful '-' # label. Thus I explicitly do 'notitle' for that case - my ($curveoptions) = @_; - my $titleoption = defined $curveoptions->{title} ? - "title \"$curveoptions->{title}\"" : "notitle"; + my ($curveoptions, $id) = @_; + my $title; + $title = $curveoptions->{title} if(defined $curveoptions->{title}); + $title = $id if $options{autolegend}; + + my $titleoption = defined $title ? "title \"$title\"" : "notitle"; $curveoptions->{options} = "$curveoptions->{extraoptions} $titleoption"; } @@ -533,7 +539,7 @@ sub getCurve push @curves, [{extraoptions => ' '}]; # push a curve with no data and no options $curveIndices{$id} = $#curves; - updateCurveOptions($curves[$#curves][0]); + updateCurveOptions($curves[$#curves][0], $id); } return $curves[$curveIndices{$id}]; } @@ -544,7 +550,7 @@ sub addCurveOption my $curve = getCurve($id); $curve->[0]{extraoptions} .= "$str "; - updateCurveOptions($curve->[0]); + updateCurveOptions($curve->[0], $id); } sub setCurveLabel @@ -553,7 +559,7 @@ sub setCurveLabel my $curve = getCurve($id); $curve->[0]{title} = $str; - updateCurveOptions($curve->[0]); + updateCurveOptions($curve->[0], $id); } # function to add a point to the plot. Assumes that the curve indexed by $idx already exists From 7823ea605436ffddfa971ae09c67e39e8c3f9d1b Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 23 Oct 2010 17:22:29 -0700 Subject: [PATCH 105/270] updated README to reflect the recent changes (--dataid, --autolegend) --- README | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README b/README index 450e1bc..0b90534 100644 --- a/README +++ b/README @@ -32,13 +32,13 @@ can appear on a single line, but all points on a line are associated with the X value that starts that line. By default, each column represents a separate curve. If sparse data is to be -plotted, this is undesireable. With the --dataindex option, each point in -the input is preceded by an integer identifying the curve the point belongs +plotted, this is undesireable. With the --dataid option, each point in the +input is preceded by string identifying the curve the point belongs to. With the previous example: seq 5 | awk '{print 2*$1, $1*$1}' | -feedGnuplot.pl --dataindex --lines --points --legend "data 0" --title "Test plot" --y2 1 +feedGnuplot.pl --dataid --lines --points --legend "data 0" --title "Test plot" --y2 1 we get 5 different curves with one point in each. The first column, as @@ -51,7 +51,10 @@ the legend commandline parameters are applied in order to curves passed in --legend "data 0" --legend "data 1" --legend "data 2", a legend would be created with "data 2" labeled, but no labels for the other curves. As many points as desired can appear on a single line, and --domain -can be used together with --dataindex. +can be used together with --dataid. + +Note that the IDs used with --dataid are general strings, NOT just +numbers. These IDs can be used to generate the plot legend with --autolegend. The script is able to produce hardcopy output with "--hardcopy outputfile". The output type is inferred from the filename with .ps, .pdf From e324a39b04be463f0fa6021e5c5f26527ad3f082 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 12:08:34 -0800 Subject: [PATCH 106/270] handle cmdline option errors as soon as possible --- feedGnuplot.pl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 5c5cdd3..9034687 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -169,6 +169,11 @@ GetOptions(\%options, 'help', 'dump') or die($usage); +if( defined $options{help} ) +{ + die($usage); +} + # set up plotting style my $style = ''; if($options{lines}) { $style .= 'lines';} @@ -176,12 +181,6 @@ if($options{points}) { $style .= 'points';} if(!$style) { $style = 'points'; } -if( defined $options{help} ) -{ - die($usage); -} - - # list containing the plot data. Each element is a reference to a list, representing the data for # one curve. The first 'point' is a hash describing various curve parameters. The rest are all # references to lists of (x,y) tuples From 5abd2dc6215900f50eb1ff2a15a78bb66e75c6cc Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 12:10:02 -0800 Subject: [PATCH 107/270] whitespace --- feedGnuplot.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 9034687..7e1a6b9 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -243,7 +243,8 @@ sub plotThread } -sub mainThread { +sub mainThread +{ local *PIPE; my $dopersist = ''; From e3b79b832a270d077daddfc42aa427ec5aba813f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 12:43:12 -0800 Subject: [PATCH 108/270] if($options{blah}) instead of if(defined $options{blah}) when possible. No longer specifying 0-defaults --- feedGnuplot.pl | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 7e1a6b9..28b5a7a 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -128,16 +128,11 @@ if(exists $ARGV[0] && !-r $ARGV[0]) unshift @ARGV, shellwords shift @ARGV; } +# everything off by default: # do not stream in the data by default # point plotting by default. # no monotonicity checks by default -my %options = ( stream => 0, - domain => 0, - dataid => 0, - points => 0, - lines => 0, - xlen => 0, - maxcurves => 100); +my %options = ( maxcurves => 100); GetOptions(\%options, 'stream!', @@ -169,7 +164,7 @@ GetOptions(\%options, 'help', 'dump') or die($usage); -if( defined $options{help} ) +if( $options{help} ) { die($usage); } @@ -196,7 +191,7 @@ my $xwindow; my $streamingFinished : shared = undef; if($options{stream}) { - if( defined $options{hardcopy}) + if( $options{hardcopy}) { $options{stream} = undef; } @@ -265,7 +260,7 @@ sub mainThread my $outputfile; my $outputfileType; - if( defined $options{hardcopy}) + if( $options{hardcopy}) { $outputfile = $options{hardcopy}; ($outputfileType) = $outputfile =~ /\.(ps|pdf|png)$/; @@ -447,7 +442,7 @@ sub mainThread { plotStoredData(); - if( defined $options{hardcopy}) + if( $options{hardcopy}) { print PIPE "set output\n"; # sleep until the plot file exists, and it is closed. Sometimes the output is From 209776528efd7481ff8f1ad8227b6afb46b7665d Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 14:14:59 -0800 Subject: [PATCH 109/270] added 3d-plotting capability --- feedGnuplot.pl | 95 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 28b5a7a..4fdd258 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -49,6 +49,8 @@ As an example, if line 3 of the input is "0 9 1 20" value, so it is ignored. If another value followed 20, we'd get another point in curve ID 20 + --[no]3d Do [not] plot in 3D. This only makes sense with --domain. + Each domain here is an (x,y) tuple --[no]stream Do [not] display the data a point at a time, as it comes in @@ -58,10 +60,9 @@ As an example, if line 3 of the input is "0 9 1 20" --[no]points Do [not] draw points --xlabel xxx Set x-axis label - --ylabel xxx Set y-axis label - - --y2label xxx Set y2-axis label + --y2label xxx Set y2-axis label. Does not apply to 3d plots + --zlabel xxx Set y-axis label. Only applies to 3d plots --title xxx Set the title of the plot @@ -71,24 +72,22 @@ As an example, if line 3 of the input is "0 9 1 20" --autolegend Use the curve IDs for the legend --xlen xxx Set the size of the x-window to plot. Omit this or set it - to 0 to plot ALL the data + to 0 to plot ALL the data. Does not make sense with 3d plots --xmin xxx Set the range for the x axis. These are ignored in a streaming plot - --xmax xxx Set the range for the x axis. These are ignored in a streaming plot - --ymin xxx Set the range for the y axis. - --ymax xxx Set the range for the y axis. - - --y2min xxx Set the range for the y2 axis. - - --y2max xxx Set the range for the y2 axis. + --y2min xxx Set the range for the y2 axis. Does not apply to 3d plots. + --y2max xxx Set the range for the y2 axis. Does not apply to 3d plots. + --zmin xxx Set the range for the z axis. Only applies to 3d plots. + --zmax xxx Set the range for the z axis. Only applies to 3d plots. --y2 xxx Plot the data specified by this curve ID on the y2 axis. - Without --dataid, the ID is just an ordered 0-based index + Without --dataid, the ID is just an ordered 0-based index. + Does not apply to 3d plots. --curvestyle xxx Additional style per curve. Give this option multiple times for multiple curves @@ -112,7 +111,8 @@ As an example, if line 3 of the input is "0 9 1 20" coordinate in the input data is monotonically increasing. If a given x-variable is in the past, all data currently cached for this curve is purged. Without --monotonic, all - data is kept. No --monotonic by default + data is kept. Does not make sense with 3d plots. + No --monotonic by default. --dump Instead of printing to gnuplot, print to STDOUT. For debugging. @@ -138,6 +138,7 @@ GetOptions(\%options, 'stream!', 'domain!', 'dataid!', + '3d!', 'lines!', 'points!', 'legend=s@', @@ -145,6 +146,7 @@ GetOptions(\%options, 'xlabel=s', 'ylabel=s', 'y2label=s', + 'zlabel=s', 'title=s', 'xlen=f', 'ymin=f', @@ -153,6 +155,8 @@ GetOptions(\%options, 'xmax=f', 'y2min=f', 'y2max=f', + 'zmin=f', + 'zmax=f', 'y2=s@', 'curvestyle=s@', 'extracmds=s@', @@ -164,11 +168,47 @@ GetOptions(\%options, 'help', 'dump') or die($usage); +# handle various cmdline-option errors if( $options{help} ) { die($usage); } +if( $options{'3d'} ) +{ + if( !$options{domain} ) + { + print STDERR "--3d only makes sense with --domain\n"; + die $usage; + } + + if( defined $options{y2min} || defined $options{y2max} || defined $options{y2} ) + { + print STDERR "--3d does not make sense with --y2...\n"; + die $usage; + } + + if( defined $options{xlen} ) + { + print STDERR "--3d does not make sense with --xlen\n"; + die $usage; + } + + if( defined $options{monotonic} ) + { + print STDERR "--3d does not make sense with --monotonic\n"; + die $usage; + } +} +else +{ + if( defined $options{zmin} || defined $options{zmax} || defined $options{zlabel} ) + { + print STDERR "--zmin/zmax/zlabel only makes sense with --3d\n"; + die $usage; + } +} + # set up plotting style my $style = ''; if($options{lines}) { $style .= 'lines';} @@ -287,6 +327,8 @@ sub mainThread $options{ymax} = '' unless defined $options{ymax}; $options{y2min} = '' unless defined $options{y2min}; $options{y2max} = '' unless defined $options{y2max}; + $options{zmin} = '' unless defined $options{zmin}; + $options{zmax} = '' unless defined $options{zmax}; print PIPE "set xtics\n"; if($options{y2}) @@ -300,11 +342,13 @@ sub mainThread # if any of the ranges are given, set the range print PIPE "set xrange [". $options{xmin} . ":" . $options{xmax} ."]\n" if length( $options{xmin} . $options{xmax} ); print PIPE "set yrange [". $options{ymin} . ":" . $options{ymax} ."]\n" if length( $options{ymin} . $options{ymax} ); + print PIPE "set zrange [". $options{zmin} . ":" . $options{zmax} ."]\n" if length( $options{zmin} . $options{zmax} ); print PIPE "set style data $style\n"; print PIPE "set grid\n"; print(PIPE "set xlabel \"" . $options{xlabel } . "\"\n") if defined $options{xlabel}; print(PIPE "set ylabel \"" . $options{ylabel } . "\"\n") if defined $options{ylabel}; + print(PIPE "set zlabel \"" . $options{zlabel } . "\"\n") if defined $options{zlabel}; print(PIPE "set y2label \"" . $options{y2label} . "\"\n") if defined $options{y2label}; print(PIPE "set title \"" . $options{title } . "\"\n") if defined $options{title}; @@ -352,7 +396,7 @@ sub mainThread # regexp for a possibly floating point, possibly scientific notation number, fully captured my $numRE = qr/([-]?[\d\.]+(?:e[-+]?\d+)?)/io; - my $xlast; + my @domain; my $haveNewData; # I should be using the // operator, but I'd like to be compatible with perl 5.8 @@ -370,11 +414,17 @@ sub mainThread # number is used) # $options{dataid} indicates whether idX is given or not (if not, the point order in the # line is used) + # 3d plots require $options{domain}, and dictate "x y" for the domain instead of just "x" if($options{domain}) { /$numRE/go or next; - $xlast = $1; + $domain[0] = $1; + if($options{'3d'}) + { + /$numRE/go or next; + $domain[1] = $1; + } } else { @@ -383,11 +433,11 @@ sub mainThread if(defined $dataQueue) { s/ ([\d]+)$//o; - $xlast = $1; + $domain[0] = $1; } else { - $xlast = $.; + $domain[0] = $.; } } @@ -399,7 +449,7 @@ sub mainThread $haveNewData = 1; pushPoint(getCurve($1), - [$xlast, $point]); + [@domain, $point]); } } else @@ -409,7 +459,7 @@ sub mainThread { $haveNewData = 1; pushPoint(getCurve($id++), - [$xlast, $point]); + [@domain, $point]); } } } @@ -422,8 +472,8 @@ sub mainThread if( $options{xlen} ) { - pruneOldData($xlast - $options{xlen}); - plotStoredData($xlast - $options{xlen}, $xlast); + pruneOldData($domain[0] - $options{xlen}); + plotStoredData($domain[0] - $options{xlen}, $domain[0]); } else { @@ -484,7 +534,8 @@ sub plotStoredData my @nonemptyCurves = grep {@$_ > 1} @curves; my @extraopts = map {$_->[0]{options}} @nonemptyCurves; - print PIPE 'plot ' . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; + my $cmd = $options{'3d'} ? 'splot ' : 'plot '; + print PIPE $cmd . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; foreach my $buf (@nonemptyCurves) { From afeaae665d6a3df63f288658d5d60576fcb34bb0 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 14:23:03 -0800 Subject: [PATCH 110/270] fixed typo --- feedGnuplot.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 4fdd258..5417c3a 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -505,7 +505,7 @@ sub mainThread } # we persist gnuplot, so we shouldn't need this sleep. However, once - # gnuplot exist, but the persistent window sticks around, you can no + # gnuplot exits, but the persistent window sticks around, you can no # longer interactively zoom the plot. So we still sleep sleep(100000); } From 497c4cc0d632ebb2465341735d9e850f679a4820 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 15:03:31 -0800 Subject: [PATCH 111/270] added option for plotting colormaps --- feedGnuplot.pl | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 5417c3a..42d2d6a 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -52,6 +52,8 @@ As an example, if line 3 of the input is "0 9 1 20" --[no]3d Do [not] plot in 3D. This only makes sense with --domain. Each domain here is an (x,y) tuple + --colormap For 3d plots, show a colormapped top-down view + --[no]stream Do [not] display the data a point at a time, as it comes in @@ -139,6 +141,7 @@ GetOptions(\%options, 'domain!', 'dataid!', '3d!', + 'colormap!', 'lines!', 'points!', 'legend=s@', @@ -174,6 +177,8 @@ if( $options{help} ) die($usage); } +if($options{colormap}) { $options{'3d'} = 1; }; # colormap implies 3d + if( $options{'3d'} ) { if( !$options{domain} ) @@ -359,6 +364,11 @@ sub mainThread } print(PIPE "set size $options{size}\n") if defined $options{size}; + if($options{colormap}) + { + print PIPE "set view map\n"; + } + # For the specified values, set the legend entries to 'title "blah blah"' if($options{legend}) { @@ -534,8 +544,22 @@ sub plotStoredData my @nonemptyCurves = grep {@$_ > 1} @curves; my @extraopts = map {$_->[0]{options}} @nonemptyCurves; - my $cmd = $options{'3d'} ? 'splot ' : 'plot '; - print PIPE $cmd . join(', ' , map({ '"-"' . $_} @extraopts) ) . "\n"; + my $body = join(', ' , map({ '"-"' . $_} @extraopts) ); + if($options{'3d'}) + { + if($options{colormap}) + { + print PIPE "splot $body palette\n"; + } + else + { + print PIPE "splot $body\n"; + } + } + else + { + print PIPE "plot $body\n"; + } foreach my $buf (@nonemptyCurves) { From 91134938a735876693a4d09c453a057ece5d2772 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 16:16:27 -0800 Subject: [PATCH 112/270] gnuplot wants the title to be given before the extra curve options, so I do that --- feedGnuplot.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 42d2d6a..ae64cf2 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -587,7 +587,7 @@ sub updateCurveOptions $title = $id if $options{autolegend}; my $titleoption = defined $title ? "title \"$title\"" : "notitle"; - $curveoptions->{options} = "$curveoptions->{extraoptions} $titleoption"; + $curveoptions->{options} = "$titleoption $curveoptions->{extraoptions}"; } sub getCurve From b684dc3dd4317b7987604a7c2974555e863b67c3 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 16:33:21 -0800 Subject: [PATCH 113/270] colormaps didn't automatically range themselves using zmin/zmax. They now do --- feedGnuplot.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index ae64cf2..77da2b7 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -367,6 +367,7 @@ sub mainThread if($options{colormap}) { print PIPE "set view map\n"; + print PIPE "set cbrange [". $options{zmin} . ":" . $options{zmax} ."]\n" if length( $options{zmin} . $options{zmax} ); } # For the specified values, set the legend entries to 'title "blah blah"' From 3ec5e7a41745ec57d98152cba280bddac788e394 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 17:11:02 -0800 Subject: [PATCH 114/270] I now support eps output --- feedGnuplot.pl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 77da2b7..e6f9ff9 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -308,13 +308,14 @@ sub mainThread if( $options{hardcopy}) { $outputfile = $options{hardcopy}; - ($outputfileType) = $outputfile =~ /\.(ps|pdf|png)$/; - if(!$outputfileType) { die("Only .ps, .pdf and .png supported\n"); } + ($outputfileType) = $outputfile =~ /\.(eps|ps|pdf|png)$/; + if(!$outputfileType) { die("Only .eps, .ps, .pdf and .png supported\n"); } my %terminalOpts = - ( ps => 'postscript solid color landscape 10', - pdf => 'pdfcairo solid color font ",10" size 11in,8.5in', - png => 'png size 1280,1024' ); + ( eps => 'postscript solid color eps 10', + ps => 'postscript solid color landscape 10', + pdf => 'pdfcairo solid color font ",10" size 11in,8.5in', + png => 'png size 1280,1024' ); print PIPE "set terminal $terminalOpts{$outputfileType}\n"; print PIPE "set output \"$outputfile\"\n"; From 141900748311494505e18bad4d2fc391fa523c44 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 3 Jan 2011 20:05:07 -0800 Subject: [PATCH 115/270] fixed incorrect handling of the palette option --- feedGnuplot.pl | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index e6f9ff9..369a630 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -549,14 +549,7 @@ sub plotStoredData my $body = join(', ' , map({ '"-"' . $_} @extraopts) ); if($options{'3d'}) { - if($options{colormap}) - { - print PIPE "splot $body palette\n"; - } - else - { - print PIPE "splot $body\n"; - } + print PIPE "splot $body\n"; } else { @@ -589,7 +582,8 @@ sub updateCurveOptions $title = $id if $options{autolegend}; my $titleoption = defined $title ? "title \"$title\"" : "notitle"; - $curveoptions->{options} = "$titleoption $curveoptions->{extraoptions}"; + my $colormapoption = $options{colormap} ? 'palette' : ''; + $curveoptions->{options} = "$titleoption $curveoptions->{extraoptions} $colormapoption"; } sub getCurve From e9f92fc7a2e178f6761fbb8dcd68de7e89dc4c44 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 14:05:38 -0800 Subject: [PATCH 116/270] added option to add a style to ALL the curves --- feedGnuplot.pl | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 369a630..2ea5aa6 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -94,6 +94,8 @@ As an example, if line 3 of the input is "0 9 1 20" --curvestyle xxx Additional style per curve. Give this option multiple times for multiple curves + --curvestyleall xxx Additional styles for ALL curves. + --extracmds xxx Additional commands. These could contain extra global styles for instance @@ -162,6 +164,7 @@ GetOptions(\%options, 'zmax=f', 'y2=s@', 'curvestyle=s@', + 'curvestyleall=s', 'extracmds=s@', 'size=s', 'square!', @@ -177,7 +180,16 @@ if( $options{help} ) die($usage); } -if($options{colormap}) { $options{'3d'} = 1; }; # colormap implies 3d +if($options{colormap}) +{ + # colormap implies 3d + $options{'3d'} = 1; + + # colormap styles all curves with palette. Seems like there should be a way to do this with a + # global setting, but I can't get that to work + $options{curvestyleall} = '' unless defined $options{curvestyleall}; + $options{curvestyleall} .= ' palette'; +} if( $options{'3d'} ) { @@ -312,7 +324,7 @@ sub mainThread if(!$outputfileType) { die("Only .eps, .ps, .pdf and .png supported\n"); } my %terminalOpts = - ( eps => 'postscript solid color eps 10', + ( eps => 'postscript solid color enhanced eps', ps => 'postscript solid color landscape 10', pdf => 'pdfcairo solid color font ",10" size 11in,8.5in', png => 'png size 1280,1024' ); @@ -582,8 +594,8 @@ sub updateCurveOptions $title = $id if $options{autolegend}; my $titleoption = defined $title ? "title \"$title\"" : "notitle"; - my $colormapoption = $options{colormap} ? 'palette' : ''; - $curveoptions->{options} = "$titleoption $curveoptions->{extraoptions} $colormapoption"; + my $extraoption = defined $options{curvestyleall} ? $options{curvestyleall} : ''; + $curveoptions->{options} = "$titleoption $curveoptions->{extraoptions} $extraoption"; } sub getCurve From e3a41a4ec515bb8743605242a6c73c0cc5d6cb13 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 15:16:05 -0800 Subject: [PATCH 117/270] If no --points or --lines is given, I no longer explicitly set a gnuplot style --- feedGnuplot.pl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 2ea5aa6..ffafc0c 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -231,8 +231,6 @@ my $style = ''; if($options{lines}) { $style .= 'lines';} if($options{points}) { $style .= 'points';} -if(!$style) { $style = 'points'; } - # list containing the plot data. Each element is a reference to a list, representing the data for # one curve. The first 'point' is a hash describing various curve parameters. The rest are all # references to lists of (x,y) tuples @@ -361,7 +359,7 @@ sub mainThread print PIPE "set xrange [". $options{xmin} . ":" . $options{xmax} ."]\n" if length( $options{xmin} . $options{xmax} ); print PIPE "set yrange [". $options{ymin} . ":" . $options{ymax} ."]\n" if length( $options{ymin} . $options{ymax} ); print PIPE "set zrange [". $options{zmin} . ":" . $options{zmax} ."]\n" if length( $options{zmin} . $options{zmax} ); - print PIPE "set style data $style\n"; + print PIPE "set style data $style\n" if $style; print PIPE "set grid\n"; print(PIPE "set xlabel \"" . $options{xlabel } . "\"\n") if defined $options{xlabel}; From 1abc70db2ffa8b817fabd1c815d6d9bec5d3ae87 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 15:36:45 -0800 Subject: [PATCH 118/270] Colormaps are now generated with plot, NOT splot. This allows some extra features to work that otherwise wouldn't (like 'with circles') --- feedGnuplot.pl | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index ffafc0c..7796a64 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -52,7 +52,7 @@ As an example, if line 3 of the input is "0 9 1 20" --[no]3d Do [not] plot in 3D. This only makes sense with --domain. Each domain here is an (x,y) tuple - --colormap For 3d plots, show a colormapped top-down view + --colormap Show a colormapped top-down view --[no]stream Do [not] display the data a point at a time, as it comes in @@ -84,8 +84,8 @@ As an example, if line 3 of the input is "0 9 1 20" --ymax xxx Set the range for the y axis. --y2min xxx Set the range for the y2 axis. Does not apply to 3d plots. --y2max xxx Set the range for the y2 axis. Does not apply to 3d plots. - --zmin xxx Set the range for the z axis. Only applies to 3d plots. - --zmax xxx Set the range for the z axis. Only applies to 3d plots. + --zmin xxx Set the range for the z axis. Only applies to 3d plots or colormaps. + --zmax xxx Set the range for the z axis. Only applies to 3d plots or colormaps. --y2 xxx Plot the data specified by this curve ID on the y2 axis. Without --dataid, the ID is just an ordered 0-based index. @@ -182,9 +182,6 @@ if( $options{help} ) if($options{colormap}) { - # colormap implies 3d - $options{'3d'} = 1; - # colormap styles all curves with palette. Seems like there should be a way to do this with a # global setting, but I can't get that to work $options{curvestyleall} = '' unless defined $options{curvestyleall}; @@ -217,11 +214,11 @@ if( $options{'3d'} ) die $usage; } } -else +elsif(!$options{colormap}) { if( defined $options{zmin} || defined $options{zmax} || defined $options{zlabel} ) { - print STDERR "--zmin/zmax/zlabel only makes sense with --3d\n"; + print STDERR "--zmin/zmax/zlabel only makes sense with --3d or --colormap\n"; die $usage; } } @@ -377,7 +374,6 @@ sub mainThread if($options{colormap}) { - print PIPE "set view map\n"; print PIPE "set cbrange [". $options{zmin} . ":" . $options{zmax} ."]\n" if length( $options{zmin} . $options{zmax} ); } @@ -442,7 +438,7 @@ sub mainThread { /$numRE/go or next; $domain[0] = $1; - if($options{'3d'}) + if($options{'3d'} || $options{colormap}) { /$numRE/go or next; $domain[1] = $1; From da87a716c1b3a15ae760190f1a6e849068fd0619 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 15:38:31 -0800 Subject: [PATCH 119/270] make sure that $options{curvestyleall} is always defined. This cleans up some things --- feedGnuplot.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 7796a64..ee06e5c 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -180,11 +180,12 @@ if( $options{help} ) die($usage); } +$options{curvestyleall} = '' unless defined $options{curvestyleall}; + if($options{colormap}) { # colormap styles all curves with palette. Seems like there should be a way to do this with a # global setting, but I can't get that to work - $options{curvestyleall} = '' unless defined $options{curvestyleall}; $options{curvestyleall} .= ' palette'; } From 030676037d9ac564c470a6353f3aa8f89d75cf43 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 15:39:57 -0800 Subject: [PATCH 120/270] my 'number' regular expression is now captured only when needed --- feedGnuplot.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index ee06e5c..4e99f6a 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -413,8 +413,8 @@ sub mainThread } } - # regexp for a possibly floating point, possibly scientific notation number, fully captured - my $numRE = qr/([-]?[\d\.]+(?:e[-+]?\d+)?)/io; + # regexp for a possibly floating point, possibly scientific notation number + my $numRE = '[-]?[\d\.]+(?:e[-+]?\d+)?'; my @domain; my $haveNewData; @@ -437,11 +437,11 @@ sub mainThread if($options{domain}) { - /$numRE/go or next; + /($numRE)/go or next; $domain[0] = $1; if($options{'3d'} || $options{colormap}) { - /$numRE/go or next; + /($numRE)/go or next; $domain[1] = $1; } } @@ -462,7 +462,7 @@ sub mainThread if($options{dataid}) { - while(/(\w+)\s+$numRE/go) + while(/(\w+)\s+($numRE)/go) { my $point = $2; From 400ed04b31cb7d9880911e866cab45857ab36635 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 15:59:57 -0800 Subject: [PATCH 121/270] style is handled completely in the main thread --- feedGnuplot.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 4e99f6a..95c9aab 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -224,11 +224,6 @@ elsif(!$options{colormap}) } } -# set up plotting style -my $style = ''; -if($options{lines}) { $style .= 'lines';} -if($options{points}) { $style .= 'points';} - # list containing the plot data. Each element is a reference to a list, representing the data for # one curve. The first 'point' is a hash describing various curve parameters. The rest are all # references to lists of (x,y) tuples @@ -353,6 +348,11 @@ sub mainThread print PIPE "set y2range [". $options{y2min} . ":" . $options{y2max} ."]\n" if length( $options{y2min} . $options{y2max} ); } + # set up plotting style + my $style = ''; + if($options{lines}) { $style .= 'lines';} + if($options{points}) { $style .= 'points';} + # if any of the ranges are given, set the range print PIPE "set xrange [". $options{xmin} . ":" . $options{xmax} ."]\n" if length( $options{xmin} . $options{xmax} ); print PIPE "set yrange [". $options{ymin} . ":" . $options{ymax} ."]\n" if length( $options{ymin} . $options{ymax} ); From f30a842af6037a46d73dbfdc7fa12b3a37fccbaf Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 16:08:22 -0800 Subject: [PATCH 122/270] I can now have more than one value for a point. This is useful for colors, point sizes, error bars, etc --- feedGnuplot.pl | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 95c9aab..fb44d92 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -118,6 +118,14 @@ As an example, if line 3 of the input is "0 9 1 20" data is kept. Does not make sense with 3d plots. No --monotonic by default. + --extraValuesPerPoint xxx + How many extra values are given for each data point. Normally this + is 0, and does not need to be specified, but sometimes we want + extra data, like for colors or point sizes or error bars, etc. + Feedgnuplot options that require this (colormap, circles) are + automatically set. This option is ONLY needed if unknown styles are used, + with --curvestyleall for instance + --dump Instead of printing to gnuplot, print to STDOUT. For debugging. OEF @@ -171,6 +179,7 @@ GetOptions(\%options, 'hardcopy=s', 'maxcurves=i', 'monotonic!', + 'extraValuesPerPoint=i', 'help', 'dump') or die($usage); @@ -288,6 +297,9 @@ sub plotThread sub mainThread { + my $valuesPerPoint = 1; + if($options{extraValuesPerPoint}) { $valuesPerPoint += $options{extraValuesPerPoint}; } + local *PIPE; my $dopersist = ''; @@ -415,6 +427,12 @@ sub mainThread # regexp for a possibly floating point, possibly scientific notation number my $numRE = '[-]?[\d\.]+(?:e[-+]?\d+)?'; + + # a point may be preceded by an id + my $pointRE = $options{dataid} ? '(\w+)\s+' : '()'; + $pointRE .= '(' . join('\s+', ($numRE) x $valuesPerPoint) . ')'; + $pointRE = qr/$pointRE/; + my @domain; my $haveNewData; @@ -460,26 +478,15 @@ sub mainThread } } - if($options{dataid}) + my $id = -1; + while (/$pointRE/go) { - while(/(\w+)\s+($numRE)/go) - { - my $point = $2; + if($1 ne '') {$id = $1;} + else {$id++; } - $haveNewData = 1; - pushPoint(getCurve($1), - [@domain, $point]); - } - } - else - { - my $id = 0; - foreach my $point (/$numRE/go) - { - $haveNewData = 1; - pushPoint(getCurve($id++), - [@domain, $point]); - } + $haveNewData = 1; + pushPoint(getCurve($id), + [@domain, split( /\s+/, $2)]); } } From 5eec77a637a99cb792643168e5824796844a3e6c Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 16:08:47 -0800 Subject: [PATCH 123/270] colormaps are now treated as 2d plots with an extra data value --- feedGnuplot.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index fb44d92..eb34716 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -52,7 +52,9 @@ As an example, if line 3 of the input is "0 9 1 20" --[no]3d Do [not] plot in 3D. This only makes sense with --domain. Each domain here is an (x,y) tuple - --colormap Show a colormapped top-down view + --colormap Show a colormapped xy plot. Requires extra data for the color. + zmin/zmax can be used to set the extents of the colors. + Automatically increments extraValuesPerPoint --[no]stream Do [not] display the data a point at a time, as it comes in @@ -299,6 +301,7 @@ sub mainThread { my $valuesPerPoint = 1; if($options{extraValuesPerPoint}) { $valuesPerPoint += $options{extraValuesPerPoint}; } + if($options{colormap}) { $valuesPerPoint++; } local *PIPE; my $dopersist = ''; @@ -457,7 +460,7 @@ sub mainThread { /($numRE)/go or next; $domain[0] = $1; - if($options{'3d'} || $options{colormap}) + if($options{'3d'}) { /($numRE)/go or next; $domain[1] = $1; From 6a748ee767153405242ed2daba67a486ce5ad782 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 16:09:03 -0800 Subject: [PATCH 124/270] added 'circles' plotting style --- feedGnuplot.pl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index eb34716..89d82b4 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -60,8 +60,9 @@ As an example, if line 3 of the input is "0 9 1 20" comes in --[no]lines Do [not] draw lines to connect consecutive points - --[no]points Do [not] draw points + --circles Plot with circles. This requires a radius be specified for + each point. Automatically increments extraValuesPerPoint --xlabel xxx Set x-axis label --ylabel xxx Set y-axis label @@ -156,6 +157,7 @@ GetOptions(\%options, 'colormap!', 'lines!', 'points!', + 'circles', 'legend=s@', 'autolegend!', 'xlabel=s', @@ -302,6 +304,7 @@ sub mainThread my $valuesPerPoint = 1; if($options{extraValuesPerPoint}) { $valuesPerPoint += $options{extraValuesPerPoint}; } if($options{colormap}) { $valuesPerPoint++; } + if($options{circles} ) { $valuesPerPoint++; } local *PIPE; my $dopersist = ''; @@ -367,6 +370,10 @@ sub mainThread my $style = ''; if($options{lines}) { $style .= 'lines';} if($options{points}) { $style .= 'points';} + if($options{circles}) + { + $options{curvestyleall} = "with circles $options{curvestyleall}"; + } # if any of the ranges are given, set the range print PIPE "set xrange [". $options{xmin} . ":" . $options{xmax} ."]\n" if length( $options{xmin} . $options{xmax} ); From 62f8a295009b81ca8d399f47934355aa2771e25e Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Thu, 6 Jan 2011 19:05:49 -0800 Subject: [PATCH 125/270] fixed broken plotting when a realtime plot has some curves run out of data --- feedGnuplot.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 89d82b4..3215514 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -556,7 +556,10 @@ sub pruneOldData if( @$xy > 1 ) { my $firstInWindow = first_index {$_->[0] >= $oldestx} @{$xy}[1..$#$xy]; - splice( @$xy, 1, $firstInWindow ) unless $firstInWindow == -1; + if($firstInWindow == -1) + { splice( @$xy, 1); } + else + { splice( @$xy, 1, $firstInWindow ); } } } } From a1fd8b11f22d2fe9a4be69b5117824e4a5bc3b96 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 17 Jan 2011 00:47:00 -0800 Subject: [PATCH 126/270] 'use warnings' instead of 'perl -w' --- feedGnuplot.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 3215514..0e4fc3b 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -1,5 +1,6 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl use strict; +use warnings; use Getopt::Long; use Time::HiRes qw( usleep ); use IO::Handle; From 4d77d6dcdca6c9b24bc6a0b4522a3e5403a154c6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 17 Jan 2011 01:00:56 -0800 Subject: [PATCH 127/270] --help now exits successfully --- feedGnuplot.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feedGnuplot.pl b/feedGnuplot.pl index 0e4fc3b..75c6392 100755 --- a/feedGnuplot.pl +++ b/feedGnuplot.pl @@ -191,7 +191,8 @@ GetOptions(\%options, # handle various cmdline-option errors if( $options{help} ) { - die($usage); + say STDERR $usage; + exit 0; } $options{curvestyleall} = '' unless defined $options{curvestyleall}; From 3c52be328434e3910a243501ca4f4ff3ef6f18ce Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 23 Jan 2011 19:56:11 -0800 Subject: [PATCH 128/270] packaged the script for CPAN --- Build.PL | 18 +++ Changes | 4 + LICENSE | 1 - MANIFEST | 11 ++ feedGnuplot.pl => bin/feedGnuplot | 176 ++++++++++++++++++++++++++++++ ignore.txt | 12 ++ 6 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 Build.PL create mode 100644 Changes delete mode 100644 LICENSE create mode 100644 MANIFEST rename feedGnuplot.pl => bin/feedGnuplot (77%) create mode 100644 ignore.txt diff --git a/Build.PL b/Build.PL new file mode 100644 index 0000000..12e1117 --- /dev/null +++ b/Build.PL @@ -0,0 +1,18 @@ +use strict; +use warnings; +use Module::Build; + +my $builder = Module::Build->new( + module_name => 'feedGnuplot', + license => 'perl', + dist_author => q{Dima Kogan }, + dist_version_from => 'bin/feedGnuplot', + build_requires => { + 'Test::Script::Run' => 0, + }, + add_to_cleanup => [ 'feedGnuplot-*' ], + create_makefile_pl => 'traditional', + script_files => ['bin/feedGnuplot'], +); + +$builder->create_build_script(); diff --git a/Changes b/Changes new file mode 100644 index 0000000..4d71c3f --- /dev/null +++ b/Changes @@ -0,0 +1,4 @@ +Revision history for feedGnuplot + +1.00 2011/01/23 + Initial version uploaded to CPAN diff --git a/LICENSE b/LICENSE deleted file mode 100644 index e58e70a..0000000 --- a/LICENSE +++ /dev/null @@ -1 +0,0 @@ -This script is released into the public domain. diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..23ae26f --- /dev/null +++ b/MANIFEST @@ -0,0 +1,11 @@ +Build.PL +Changes +MANIFEST +README +bin/feedGnuplot +t/00-load.t +t/manifest.t +t/pod-coverage.t +t/pod.t +Makefile.PL +META.yml diff --git a/feedGnuplot.pl b/bin/feedGnuplot similarity index 77% rename from feedGnuplot.pl rename to bin/feedGnuplot index 75c6392..5e16a5c 100755 --- a/feedGnuplot.pl +++ b/bin/feedGnuplot @@ -10,6 +10,8 @@ use threads::shared; use Thread::Queue; use Text::ParseWords; +our $VERSION = '1.00'; + open(GNUPLOT_VERSION, 'gnuplot --version |'); my ($gnuplotVersion) = =~ /gnuplot\s*(\d*\.\d*)/; if(!$gnuplotVersion) @@ -674,3 +676,177 @@ sub pushPoint push @$curve, $xy; } + + +__END__ + +=head1 NAME + +feedGnuplot - A pipe-oriented frontend to Gnuplot + +=head1 SYNOPSIS + +Simple plotting of stored data: + + $ seq 5 | awk '{print 2*$1, $1*$1}' + 2 1 + 4 4 + 6 9 + 8 16 + 10 25 + + $ seq 5 | awk '{print 2*$1, $1*$1}' | + feedGnuplot --lines --points --legend "data 0" --title "Test plot" --y2 1 + +Simple real-time plotting example: plot how much data is received on the wlan0 +network interface in bytes/second (uses bash, awk and Linux): + + $ while true; do sleep 1; cat /proc/net/dev; done | + awk '/wlan0/ {if(b) {print $2-b; fflush()} b=$2}' | + feedGnuplot --lines --stream --xlen 10 --ylabel 'Bytes/sec' --xlabel seconds + +=head1 DESCRIPTION + +This is a flexible, command-line-oriented frontend to Gnuplot. It creates +plots from data coming in on STDIN or given in a filename passed on the +commandline. Various data representations are supported, as is hardcopy +output and streaming display of live data. A simple example: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot + +You should see a plot with two curves: one on the y1 axis (left) and the other +on the y2 axis (right). The plots should have a legend and a title. The C +command generates some data to plot and the C reads it in from +STDIN and generates the plot. The invocation is just an example; more +interesting things would be plotted in normal usage. None of the +commandline-options are required for the most basic plotting. Input parsing is +flexible; every line need not have the same number of points. New curves will be +created as needed. + +The most commonly used functionality of gnuplot is supported directly by the +script. Anything not directly supported can still be done with the +C<--extracmds> and C<--curvestyle> options. + +=head2 Data formats + +=head3 Domain selection + +There are 2 main commandline options to control the interpretation of the input +data. If C<--domain> is passed in, the first value on each line of input is +interpreted as the I-value for the rest of the data on that line. Without +C<--domain> the I-value is the line number, and the first value on a line is +a plain data point like the others. Default is C<--nodomain>. Thus the example +above produced 2 curves, with B<1,2,3,4,5> as the I-values. If we run the +same command with --domain: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot --domain + +we get only 1 curve, with B<2,4,6,8,10> as the I-values. As many points as +desired can appear on a single line, but all points on a line are associated +with the I-value at the start of that line. + +=head3 Curve indexing + +By default, each column represents a separate curve. This works unless sparse +data is to be plotted. With the C<--dataid> option, each point is represented by +2 values: a string identifying the curve, and the value itself. If we add +C<--dataid> to the original example: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot --dataid --autolegend + +we get 5 different curves with one point in each. The first column, as produced +by awk, is B<2,4,6,8,10>. These are interpreted as the IDs of the curves to be +plotted. The C<--autolegend> option adds a legend using the given IDs to label +the curves. The IDs need not be numbers; generic strings are accepted. As many +points as desired can appear on a single line. C<--domain> can be used in +conjunction with C<--dataid>. + +=head3 3D data + +To plot 3D data, pass in C<--3d> (for 3D curves) or C<--colormap> (top-down +view, color encoding I). C<--domain> MUST be given when plotting 3D data to +avoid domain ambiguity. If 3D data is being plotted, there are by definition 2 +domain values instead of one (I as a function of I and I instead of +I as a function of I). Thus the first 2 values on each line are +interpreted as the domain instead of just 1. The rest of the processing happens +the same way as before. + +=head2 Real-time streaming data + +To plot display realtime data, pass in the C<--stream> option. Data will then be +plotted as it is received, with the refresh rate limited to 1Hz (currently +hard-coded). To plot only the most recent data (instead of I the data), +C<--xlen windowsize> can be given. This will create an constantly-updating, +scrolling view of the recent past. The windowsize is given in domain units +(passed-in values if C<--domain> or line numbers otherwise). + +=head2 Hardcopy output + +The script is able to produce hardcopy output with C<--hardcopy outputfile>. The +output type is inferred from the filename with B<.ps>, B<.eps>, B<.pdf> and +B<.png> currently supported. + +=head2 Self-plotting data files + +This script can be used to create self-plotting data files. A self-plotting, +executable data file C is formatted as + + $ cat data + #!/usr/bin/feedGnuplot --lines --points + 2 1 + 4 4 + 6 9 + 8 16 + 10 25 + 12 36 + 14 49 + 16 64 + 18 81 + 20 100 + 22 121 + 24 144 + 26 169 + 28 196 + 30 225 + +This is the shebang (#!) line followed by the data, formatted as before. The +data file can be plotted simply with + + $ ./data + +The caveats here are that on Linux the whole #! line is limited to 127 charaters +and that the full path to feedGnuplot must be given. The 127 character limit is +a serious limitation, but this can likely be resolved with a kernel patch. I +have only tried on Linux 2.6. + +=head2 Further help + +All the options are described with + + $ feedGnuplot --help + +=head1 ACKNOWLEDGEMENT + +This program is originally based on the driveGnuPlots.pl script from +Thanassis Tsiodras. It is available from his site at +L + +=head1 REPOSITORY + +L + +=head1 AUTHOR + +Dima Kogan, C<< >> + +=head1 LICENSE AND COPYRIGHT + +Copyright 2011 Dima Kogan. + +This program is free software; you can redistribute it and/or modify it +under the terms of either: the GNU General Public License as published +by the Free Software Foundation; or the Artistic License. + +See http://dev.perl.org/licenses/ for more information. + +=cut diff --git a/ignore.txt b/ignore.txt new file mode 100644 index 0000000..f7a02d0 --- /dev/null +++ b/ignore.txt @@ -0,0 +1,12 @@ +blib* +Makefile +Makefile.old +Build +Build.bat +_build* +pm_to_blib* +*.tar.gz +.lwpcookies +cover_db +pod2htm*.tmp +feedGnuplot-* From 984a5a253977d6305b2abc001c92bf6da5371084 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 23 Jan 2011 19:57:23 -0800 Subject: [PATCH 129/270] added cpan tests --- t/00-load.t | 7 +++++++ t/manifest.t | 13 +++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 t/00-load.t create mode 100644 t/manifest.t diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..5687318 --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,7 @@ +#!/usr/bin/perl + +use Test::More tests => 1; +use Test::Script::Run; + +run_ok( 'feedGnuplot', ['--help'], 'feedGnuplot can run'); + diff --git a/t/manifest.t b/t/manifest.t new file mode 100644 index 0000000..45eb83f --- /dev/null +++ b/t/manifest.t @@ -0,0 +1,13 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +eval "use Test::CheckManifest 0.9"; +plan skip_all => "Test::CheckManifest 0.9 required" if $@; +ok_manifest(); From 4150a48974090537e55ff989f87f6bdbe8c78f9f Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 23 Jan 2011 19:58:08 -0800 Subject: [PATCH 130/270] scrubbed manifest --- MANIFEST | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MANIFEST b/MANIFEST index 23ae26f..3f819ec 100644 --- a/MANIFEST +++ b/MANIFEST @@ -5,7 +5,3 @@ README bin/feedGnuplot t/00-load.t t/manifest.t -t/pod-coverage.t -t/pod.t -Makefile.PL -META.yml From e3bfca4ce70ab278b52162557950cab3ac40f615 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 23 Jan 2011 20:12:36 -0800 Subject: [PATCH 131/270] added some more cpan distribution files --- MANIFEST | 2 ++ META.yml | 17 +++++++++++++++++ Makefile.PL | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 META.yml create mode 100644 Makefile.PL diff --git a/MANIFEST b/MANIFEST index 3f819ec..e6fa2ba 100644 --- a/MANIFEST +++ b/MANIFEST @@ -5,3 +5,5 @@ README bin/feedGnuplot t/00-load.t t/manifest.t +Makefile.PL +META.yml diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..7a30d27 --- /dev/null +++ b/META.yml @@ -0,0 +1,17 @@ +--- +name: feedGnuplot +version: 1.00 +author: + - 'Dima Kogan ' +abstract: A pipe-oriented frontend to Gnuplot +license: perl +resources: + license: http://dev.perl.org/licenses/ +build_requires: + Test::Script::Run: 0 +configure_requires: + Module::Build: 0.340201 +generated_by: Module::Build version 0.340201 +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..cd28fe6 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,16 @@ +# Note: this file was auto-generated by Module::Build::Compat version 0.340201 +use ExtUtils::MakeMaker; +WriteMakefile +( + 'NAME' => 'feedGnuplot', + 'VERSION_FROM' => 'bin/feedGnuplot', + 'PREREQ_PM' => { + 'Test::Script::Run' => 0 + }, + 'INSTALLDIRS' => 'site', + 'EXE_FILES' => [ + 'bin/feedGnuplot' + ], + 'PL_FILES' => {} + ) +; From d9593759ca9546a5754f34b0d557afe844df2ac6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 23 Jan 2011 22:28:17 -0800 Subject: [PATCH 132/270] corrected and extended documentation --- bin/feedGnuplot | 79 +++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/bin/feedGnuplot b/bin/feedGnuplot index 5e16a5c..2520587 100755 --- a/bin/feedGnuplot +++ b/bin/feedGnuplot @@ -128,9 +128,9 @@ As an example, if line 3 of the input is "0 9 1 20" How many extra values are given for each data point. Normally this is 0, and does not need to be specified, but sometimes we want extra data, like for colors or point sizes or error bars, etc. - Feedgnuplot options that require this (colormap, circles) are - automatically set. This option is ONLY needed if unknown styles are used, - with --curvestyleall for instance + feedGnuplot options that require this (colormap, circles) + automatically set it. This option is ONLY needed if unknown styles are + used, with --curvestyleall for instance --dump Instead of printing to gnuplot, print to STDOUT. For debugging. @@ -714,29 +714,36 @@ output and streaming display of live data. A simple example: $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot -You should see a plot with two curves: one on the y1 axis (left) and the other -on the y2 axis (right). The plots should have a legend and a title. The C -command generates some data to plot and the C reads it in from -STDIN and generates the plot. The invocation is just an example; more -interesting things would be plotted in normal usage. None of the -commandline-options are required for the most basic plotting. Input parsing is -flexible; every line need not have the same number of points. New curves will be -created as needed. +You should see a plot with two curves. The C command generates some data to +plot and the C reads it in from STDIN and generates the plot. The + invocation is just an example; more interesting things would be plotted in +normal usage. None of the commandline-options are required for the most basic +plotting. Input parsing is flexible; every line need not have the same number of +points. New curves will be created as needed. The most commonly used functionality of gnuplot is supported directly by the script. Anything not directly supported can still be done with the -C<--extracmds> and C<--curvestyle> options. +C<--extracmds> and C<--curvestyle> options. Arbitrary gnuplot commands can be +passed in with C<--extracmds>. For example, to turn off the grid, pass in +C<--extracmds 'unset grid'>. As many of these options as needed can be pased +in. To add arbitrary curve styles, use C<--curvestyle extrastyle>. Pass these +more than once to affect more than one curve. To apply an extra style to I +the curves, pass in C<--curvestyleall extrastyle>. =head2 Data formats +By default, each value present in the incoming data represents a distinct data +point, as demonstrated in the above example (we had 10 numbers in the input and +10 points in the plot). If requested, the script supports more sophisticated +interpretation of input data + =head3 Domain selection -There are 2 main commandline options to control the interpretation of the input -data. If C<--domain> is passed in, the first value on each line of input is +If C<--domain> is passed in, the first value on each line of input is interpreted as the I-value for the rest of the data on that line. Without C<--domain> the I-value is the line number, and the first value on a line is a plain data point like the others. Default is C<--nodomain>. Thus the example -above produced 2 curves, with B<1,2,3,4,5> as the I-values. If we run the +above produces 2 curves, with B<1,2,3,4,5> as the I-values. If we run the same command with --domain: $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot --domain @@ -747,7 +754,7 @@ with the I-value at the start of that line. =head3 Curve indexing -By default, each column represents a separate curve. This works unless sparse +By default, each column represents a separate curve. This is fine unless sparse data is to be plotted. With the C<--dataid> option, each point is represented by 2 values: a string identifying the curve, and the value itself. If we add C<--dataid> to the original example: @@ -755,30 +762,46 @@ C<--dataid> to the original example: $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot --dataid --autolegend we get 5 different curves with one point in each. The first column, as produced -by awk, is B<2,4,6,8,10>. These are interpreted as the IDs of the curves to be -plotted. The C<--autolegend> option adds a legend using the given IDs to label -the curves. The IDs need not be numbers; generic strings are accepted. As many -points as desired can appear on a single line. C<--domain> can be used in +by C, is B<2,4,6,8,10>. These are interpreted as the IDs of the curves to +be plotted. The C<--autolegend> option adds a legend using the given IDs to +label the curves. The IDs need not be numbers; generic strings are accepted. As +many points as desired can appear on a single line. C<--domain> can be used in conjunction with C<--dataid>. +=head3 Multi-value style support + +Depending on how gnuplot is plotting the data, more than one value may be needed +to represent a single point. For example, the script has support to plot all the +data with C<--circles>. This requires a radius to be specified for each point in +addition to the position of the point. Thus, when plotting with C<--circles>, 2 +numbers are read for each data point instead of 1. A similar situation exists +with C<--colormap> where each point contains the position I the +color. There are other gnuplot styles that require more data (such as error +bars), but none of these are directly supported by the script. They can still be +used, though, by specifying the specific style with C<--curvestyle>, and +specifying how many extra values are needed for each point with +C<--extraValuesPerPoint extra>. C<--extraValuesPerPoint> is ONLY needed for the +styles not explicitly supported; supported styles set that variable +automatically. + =head3 3D data -To plot 3D data, pass in C<--3d> (for 3D curves) or C<--colormap> (top-down -view, color encoding I). C<--domain> MUST be given when plotting 3D data to -avoid domain ambiguity. If 3D data is being plotted, there are by definition 2 -domain values instead of one (I as a function of I and I instead of -I as a function of I). Thus the first 2 values on each line are +To plot 3D data, pass in C<--3d>. C<--domain> MUST be given when plotting 3D +data to avoid domain ambiguity. If 3D data is being plotted, there are by +definition 2 domain values instead of one (I as a function of I and I +instead of I as a function of I). Thus the first 2 values on each line are interpreted as the domain instead of just 1. The rest of the processing happens the same way as before. =head2 Real-time streaming data -To plot display realtime data, pass in the C<--stream> option. Data will then be +To plot real-time data, pass in the C<--stream> option. Data will then be plotted as it is received, with the refresh rate limited to 1Hz (currently hard-coded). To plot only the most recent data (instead of I the data), C<--xlen windowsize> can be given. This will create an constantly-updating, -scrolling view of the recent past. The windowsize is given in domain units -(passed-in values if C<--domain> or line numbers otherwise). +scrolling view of the recent past. C should be replaced by the +desired length of the domain window to plot, in domain units (passed-in values +if C<--domain> or line numbers otherwise). =head2 Hardcopy output From 2912b90f40673d65907c6d4196e02a8bce09c203 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 23 Jan 2011 23:10:47 -0800 Subject: [PATCH 133/270] removed old README file --- README | 115 ----------------------------- README.pod | 193 ++++++++++++++++++++++++++++++++++++++++++++++++ bin/feedGnuplot | 1 - 3 files changed, 193 insertions(+), 116 deletions(-) delete mode 100644 README create mode 100644 README.pod diff --git a/README b/README deleted file mode 100644 index 0b90534..0000000 --- a/README +++ /dev/null @@ -1,115 +0,0 @@ -feedGnuplot README -================== - -This is a flexible, command-line-oriented frontend to Gnuplot. It creates -plots from data coming in on STDIN or given in a filename passed on the -commandline. Various data representations are supported, as is hardcopy -output and streaming display of live data. A simple example: - - -seq 5 | awk '{print 2*$1, $1*$1}' | -feedGnuplot.pl --lines --points --legend "data 0" --title "Test plot" --y2 1 - - -You should see a plot with two curves (one on the y1 axis and the other on -the y2 axis), a legend and a title. The first line of the example generates -some data to plot and the second reads it in from STDIN and generates the -plot. None of the commandline-options are required for the most basic -plotting. Input parsing is flexible; every line need not have the same -number of points. New curves will be created as needed. - -By default, the line number of the incoming data is used for the x-axis. To -plot an x-y dataset, feed in the x values as the first element in every line -and pass in --domain. With the previous example: - - -seq 5 | awk '{print 2*$1, $1*$1}' | -feedGnuplot.pl --domain --lines --points --legend "data 0" --title "Test plot" --y2 1 - - -we get only one curve, with different x values. As many points as desired -can appear on a single line, but all points on a line are associated with -the X value that starts that line. - -By default, each column represents a separate curve. If sparse data is to be -plotted, this is undesireable. With the --dataid option, each point in the -input is preceded by string identifying the curve the point belongs -to. With the previous example: - - -seq 5 | awk '{print 2*$1, $1*$1}' | -feedGnuplot.pl --dataid --lines --points --legend "data 0" --title "Test plot" --y2 1 - - -we get 5 different curves with one point in each. The first column, as -produced by awk, is '2,4,6,8,10'. These are interpreted as the indices of -the curves to be plotted. The feedGnuplot.pl script created 11 different -curves (0-10 inclusive), but only 5 of them were given any data. Note that -with this invocation of the example no legend was created. This is because -the legend commandline parameters are applied in order to curves -0,1,2,... Above, "data 0" applied to curve 0, which had no data. If we -passed in --legend "data 0" --legend "data 1" --legend "data 2", a legend -would be created with "data 2" labeled, but no labels for the other -curves. As many points as desired can appear on a single line, and --domain -can be used together with --dataid. - -Note that the IDs used with --dataid are general strings, NOT just -numbers. These IDs can be used to generate the plot legend with --autolegend. - -The script is able to produce hardcopy output with "--hardcopy -outputfile". The output type is inferred from the filename with .ps, .pdf -and .png currently supported. - -If live data is received in realtime, feedGnuplot.pl can be used to produce a -realtime display by passing in the --stream option. The "--xlen windowsize" -option can be passed in also to plot a scrolling window, containing the last -windowsize-worth of data (windowsize has the units of the x axis, whether it -is a point index or the passed-in domain). If --xlen is omitted or set to 0, -all of the available data is plotted, with no moving window. The realtime data -is updated at 1 Hz, so the script can handle rapidly-incoming data without -spending all of its time replotting. Example: - - -seq 500 | awk '{print 2*$1, $1*$1; system("sleep 2"); fflush()}' | -feedGnuplot.pl --stream --lines --points --legend "data 0" --title "Test plot" --y2 1 - - -This script can be used to generate self-plotting data files. If a file -called 'data' is created with: - - -#!/usr/local/bin/feedGnuplot.pl --lines --points --legend "data 0" --title "Test plot" --y2 1 -2 1 -4 4 -6 9 -8 16 -10 25 -12 36 -14 49 -16 64 -18 81 -20 100 -22 121 -24 144 -26 169 -28 196 -30 225 - - -This file can be plotted with - - -bash$ ./tst - - -The caveats here are that on Linux the whole #! line is limited to 127 -charaters and that the full path to feedGnuplot.pl must be given. - -For more information, invoke with --help, or read the source. Any bugs or -suggestions should be addressed to dkogan@cds.caltech.edu. The latest -version of the script is available at http://github.com/dkogan/feedgnuplot - - -This program is originally based on the driveGnuPlots.pl script from -Thanassis Tsiodras. It is available from his site at -http://users.softlab.ece.ntua.gr/~ttsiod/gnuplotStreaming.html diff --git a/README.pod b/README.pod new file mode 100644 index 0000000..c9ca34b --- /dev/null +++ b/README.pod @@ -0,0 +1,193 @@ +=head1 NAME + +feedGnuplot - A pipe-oriented frontend to Gnuplot + +=head1 SYNOPSIS + +Simple plotting of stored data: + + $ seq 5 | awk '{print 2*$1, $1*$1}' + 2 1 + 4 4 + 6 9 + 8 16 + 10 25 + + $ seq 5 | awk '{print 2*$1, $1*$1}' | + feedGnuplot --lines --points --legend "data 0" --title "Test plot" --y2 1 + +Simple real-time plotting example: plot how much data is received on the wlan0 +network interface in bytes/second (uses bash, awk and Linux): + + $ while true; do sleep 1; cat /proc/net/dev; done | + awk '/wlan0/ {if(b) {print $2-b; fflush()} b=$2}' | + feedGnuplot --lines --stream --xlen 10 --ylabel 'Bytes/sec' --xlabel seconds + +=head1 DESCRIPTION + +This is a flexible, command-line-oriented frontend to Gnuplot. It creates +plots from data coming in on STDIN or given in a filename passed on the +commandline. Various data representations are supported, as is hardcopy +output and streaming display of live data. A simple example: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot + +You should see a plot with two curves. The C command generates some data to +plot and the C reads it in from STDIN and generates the plot. The + invocation is just an example; more interesting things would be plotted in +normal usage. None of the commandline-options are required for the most basic +plotting. Input parsing is flexible; every line need not have the same number of +points. New curves will be created as needed. + +The most commonly used functionality of gnuplot is supported directly by the +script. Anything not directly supported can still be done with the +C<--extracmds> and C<--curvestyle> options. Arbitrary gnuplot commands can be +passed in with C<--extracmds>. For example, to turn off the grid, pass in +C<--extracmds 'unset grid'>. As many of these options as needed can be pased +in. To add arbitrary curve styles, use C<--curvestyle extrastyle>. Pass these +more than once to affect more than one curve. To apply an extra style to I +the curves, pass in C<--curvestyleall extrastyle>. + +=head2 Data formats + +By default, each value present in the incoming data represents a distinct data +point, as demonstrated in the above example (we had 10 numbers in the input and +10 points in the plot). If requested, the script supports more sophisticated +interpretation of input data + +=head3 Domain selection + +If C<--domain> is passed in, the first value on each line of input is +interpreted as the I-value for the rest of the data on that line. Without +C<--domain> the I-value is the line number, and the first value on a line is +a plain data point like the others. Default is C<--nodomain>. Thus the example +above produces 2 curves, with B<1,2,3,4,5> as the I-values. If we run the +same command with --domain: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot --domain + +we get only 1 curve, with B<2,4,6,8,10> as the I-values. As many points as +desired can appear on a single line, but all points on a line are associated +with the I-value at the start of that line. + +=head3 Curve indexing + +By default, each column represents a separate curve. This is fine unless sparse +data is to be plotted. With the C<--dataid> option, each point is represented by +2 values: a string identifying the curve, and the value itself. If we add +C<--dataid> to the original example: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedGnuplot --dataid --autolegend + +we get 5 different curves with one point in each. The first column, as produced +by C, is B<2,4,6,8,10>. These are interpreted as the IDs of the curves to +be plotted. The C<--autolegend> option adds a legend using the given IDs to +label the curves. The IDs need not be numbers; generic strings are accepted. As +many points as desired can appear on a single line. C<--domain> can be used in +conjunction with C<--dataid>. + +=head3 Multi-value style support + +Depending on how gnuplot is plotting the data, more than one value may be needed +to represent a single point. For example, the script has support to plot all the +data with C<--circles>. This requires a radius to be specified for each point in +addition to the position of the point. Thus, when plotting with C<--circles>, 2 +numbers are read for each data point instead of 1. A similar situation exists +with C<--colormap> where each point contains the position I the +color. There are other gnuplot styles that require more data (such as error +bars), but none of these are directly supported by the script. They can still be +used, though, by specifying the specific style with C<--curvestyle>, and +specifying how many extra values are needed for each point with +C<--extraValuesPerPoint extra>. C<--extraValuesPerPoint> is ONLY needed for the +styles not explicitly supported; supported styles set that variable +automatically. + +=head3 3D data + +To plot 3D data, pass in C<--3d>. C<--domain> MUST be given when plotting 3D +data to avoid domain ambiguity. If 3D data is being plotted, there are by +definition 2 domain values instead of one (I as a function of I and I +instead of I as a function of I). Thus the first 2 values on each line are +interpreted as the domain instead of just 1. The rest of the processing happens +the same way as before. + +=head2 Real-time streaming data + +To plot real-time data, pass in the C<--stream> option. Data will then be +plotted as it is received, with the refresh rate limited to 1Hz (currently +hard-coded). To plot only the most recent data (instead of I the data), +C<--xlen windowsize> can be given. This will create an constantly-updating, +scrolling view of the recent past. C should be replaced by the +desired length of the domain window to plot, in domain units (passed-in values +if C<--domain> or line numbers otherwise). + +=head2 Hardcopy output + +The script is able to produce hardcopy output with C<--hardcopy outputfile>. The +output type is inferred from the filename with B<.ps>, B<.eps>, B<.pdf> and +B<.png> currently supported. + +=head2 Self-plotting data files + +This script can be used to create self-plotting data files. A self-plotting, +executable data file C is formatted as + + $ cat data + #!/usr/bin/feedGnuplot --lines --points + 2 1 + 4 4 + 6 9 + 8 16 + 10 25 + 12 36 + 14 49 + 16 64 + 18 81 + 20 100 + 22 121 + 24 144 + 26 169 + 28 196 + 30 225 + +This is the shebang (#!) line followed by the data, formatted as before. The +data file can be plotted simply with + + $ ./data + +The caveats here are that on Linux the whole #! line is limited to 127 charaters +and that the full path to feedGnuplot must be given. The 127 character limit is +a serious limitation, but this can likely be resolved with a kernel patch. I +have only tried on Linux 2.6. + +=head2 Further help + +All the options are described with + + $ feedGnuplot --help + +=head1 ACKNOWLEDGEMENT + +This program is originally based on the driveGnuPlots.pl script from +Thanassis Tsiodras. It is available from his site at +L + +=head1 REPOSITORY + +L + +=head1 AUTHOR + +Dima Kogan, C<< >> + +=head1 LICENSE AND COPYRIGHT + +Copyright 2011 Dima Kogan. + +This program is free software; you can redistribute it and/or modify it +under the terms of either: the GNU General Public License as published +by the Free Software Foundation; or the Artistic License. + +See http://dev.perl.org/licenses/ for more information. + +=cut diff --git a/bin/feedGnuplot b/bin/feedGnuplot index 2520587..519ab14 100755 --- a/bin/feedGnuplot +++ b/bin/feedGnuplot @@ -677,7 +677,6 @@ sub pushPoint push @$curve, $xy; } - __END__ =head1 NAME From 46e0064a33d0a9f2f723834c121e10685f08e2f3 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 23 Jan 2011 23:40:15 -0800 Subject: [PATCH 134/270] version bump --- Changes | 3 +++ bin/feedGnuplot | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Changes b/Changes index 4d71c3f..e6244af 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,7 @@ Revision history for feedGnuplot +1.01 2011/01/23 + Documentation and packaging updates + 1.00 2011/01/23 Initial version uploaded to CPAN diff --git a/bin/feedGnuplot b/bin/feedGnuplot index 519ab14..7f68ac9 100755 --- a/bin/feedGnuplot +++ b/bin/feedGnuplot @@ -10,7 +10,7 @@ use threads::shared; use Thread::Queue; use Text::ParseWords; -our $VERSION = '1.00'; +our $VERSION = '1.01'; open(GNUPLOT_VERSION, 'gnuplot --version |'); my ($gnuplotVersion) = =~ /gnuplot\s*(\d*\.\d*)/; From 1bfbad17b5e65de366fc71b7eb398468602d2bcb Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 23 Jan 2011 23:42:37 -0800 Subject: [PATCH 135/270] manifest now reflects the new status of README --- MANIFEST | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST b/MANIFEST index e6fa2ba..b1bf278 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,7 +1,7 @@ Build.PL Changes MANIFEST -README +README.pod bin/feedGnuplot t/00-load.t t/manifest.t From bbf745dbdb5c52c858f413ee5d81a32733e4e812 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 24 Jan 2011 00:38:01 -0800 Subject: [PATCH 136/270] converted to ExtUtils::MakeMaker --- Build.PL | 18 ------------------ MANIFEST | 5 +---- META.yml | 17 ----------------- Makefile.PL | 32 ++++++++++++++++++-------------- 4 files changed, 19 insertions(+), 53 deletions(-) delete mode 100644 Build.PL delete mode 100644 META.yml diff --git a/Build.PL b/Build.PL deleted file mode 100644 index 12e1117..0000000 --- a/Build.PL +++ /dev/null @@ -1,18 +0,0 @@ -use strict; -use warnings; -use Module::Build; - -my $builder = Module::Build->new( - module_name => 'feedGnuplot', - license => 'perl', - dist_author => q{Dima Kogan }, - dist_version_from => 'bin/feedGnuplot', - build_requires => { - 'Test::Script::Run' => 0, - }, - add_to_cleanup => [ 'feedGnuplot-*' ], - create_makefile_pl => 'traditional', - script_files => ['bin/feedGnuplot'], -); - -$builder->create_build_script(); diff --git a/MANIFEST b/MANIFEST index b1bf278..e7aa2fd 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,9 +1,6 @@ -Build.PL +Makefile.PL Changes MANIFEST -README.pod bin/feedGnuplot t/00-load.t t/manifest.t -Makefile.PL -META.yml diff --git a/META.yml b/META.yml deleted file mode 100644 index 7a30d27..0000000 --- a/META.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: feedGnuplot -version: 1.00 -author: - - 'Dima Kogan ' -abstract: A pipe-oriented frontend to Gnuplot -license: perl -resources: - license: http://dev.perl.org/licenses/ -build_requires: - Test::Script::Run: 0 -configure_requires: - Module::Build: 0.340201 -generated_by: Module::Build version 0.340201 -meta-spec: - url: http://module-build.sourceforge.net/META-spec-v1.4.html - version: 1.4 diff --git a/Makefile.PL b/Makefile.PL index cd28fe6..30c1bd4 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,16 +1,20 @@ -# Note: this file was auto-generated by Module::Build::Compat version 0.340201 +use strict; +use warnings; use ExtUtils::MakeMaker; + WriteMakefile -( - 'NAME' => 'feedGnuplot', - 'VERSION_FROM' => 'bin/feedGnuplot', - 'PREREQ_PM' => { - 'Test::Script::Run' => 0 - }, - 'INSTALLDIRS' => 'site', - 'EXE_FILES' => [ - 'bin/feedGnuplot' - ], - 'PL_FILES' => {} - ) -; + ( + NAME => 'feedGnuplot', + AUTHOR => q{Dima Kogan }, + VERSION_FROM => 'bin/feedGnuplot', + ABSTRACT_FROM => 'bin/feedGnuplot', + ($ExtUtils::MakeMaker::VERSION >= 6.3002 + ? ('LICENSE' => 'perl') + : ()), + PL_FILES => {}, + EXE_FILES => [ 'bin/feedGnuplot' ], + PREREQ_PM => { 'Test::Script::Run' => 0 }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'feedGnuplot-*' }, + ); + From 441636694b15d8f7c01fbab8c3589f1bbf14cc94 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Mon, 24 Jan 2011 00:38:46 -0800 Subject: [PATCH 137/270] Makefile.PL now extracts the POD into README.pod --- Makefile.PL | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile.PL b/Makefile.PL index 30c1bd4..e295533 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -18,3 +18,10 @@ WriteMakefile clean => { FILES => 'feedGnuplot-*' }, ); +# reroute the main POD into a separate README.pod +open SCRIPT, 'bin/feedGnuplot' or die "Couldn't open main script"; +open README, '>README.pod' or die "Couldn't open README.pod"; +while(