Compare commits

...

41 Commits

Author SHA1 Message Date
Dima Kogan
8c39242986 added explicit LICENSE file 2012-09-11 13:04:45 -07:00
Dima Kogan
2934a76fdd fixed install instructions to work with the moved debian directory 2012-09-11 12:57:41 -07:00
Dima Kogan
614bbfe848 added the changelog to the manifest 2012-09-11 11:17:32 -07:00
Dima Kogan
265062904f Makefile.PL gets the version from the Changes file, not debian/changelog 2012-09-11 11:17:12 -07:00
Dima Kogan
55ba185ec5 added non-packaging Changes file 2012-09-11 11:15:47 -07:00
Dima Kogan
0780c10b18 moving to non-native packages. debian directory moved. 2012-09-11 11:12:30 -07:00
Dima Kogan
061cb0c0af allowing uploads by DMs 2012-09-10 23:40:29 -07:00
Dima Kogan
08b827d81b debian changelog now closes the ITP bug 2012-09-10 23:30:59 -07:00
Dima Kogan
b91eb7f746 debian/copyright has a single license for the whole package 2012-09-10 23:27:12 -07:00
Dima Kogan
9148a3e5e9 more standard copyright file 2012-09-10 21:07:22 -07:00
Dima Kogan
3d53e25c22 updated debian standards version 2012-09-10 20:55:49 -07:00
Dima Kogan
ba1715446b version bump 2012-09-10 20:48:34 -07:00
Dima Kogan
c875120dbd cleaned up debian/control 2012-09-10 20:45:12 -07:00
Dima Kogan
1f350add09 Force manpage to go into section '1' NOT '1p' 2012-09-10 18:55:53 -07:00
Dima Kogan
d36082ab32 updated package description 2012-09-10 18:31:28 -07:00
Dima Kogan
2d7bf52a45 removed debian/watch
I have a native package at this point, so I'll make new tags ONLY when a new
packaged release is cut. If this ever changes, a watch file will be re-added
2012-09-10 18:28:46 -07:00
Dima Kogan
5b20a2389a using more up-to-date copyright format spec 2012-09-10 18:26:21 -07:00
Dima Kogan
892e8266c8 version bump 2012-09-03 08:33:36 -07:00
Dima Kogan
cb59f1b3bc removed --size option 2012-09-03 08:28:51 -07:00
Dima Kogan
469461cf00 version bump 2012-09-02 23:53:17 -07:00
Dima Kogan
54f3751270 fixed regression to allow no given extracmds, histogram or y2 options 2012-09-02 23:49:40 -07:00
Dima Kogan
01de359dcd Makefile.PL now handles the new POD structure 2012-08-31 11:30:24 -07:00
Dima Kogan
0c18ccc7db added POD to the manifest 2012-08-31 11:28:31 -07:00
Dima Kogan
a285735961 Makefile.PL no longer need to make the README.pod 2012-08-31 11:19:48 -07:00
Dima Kogan
d28ef06cff documentation correction 2012-08-31 11:19:48 -07:00
Dima Kogan
0ddc0bd0bd updated copyright dates 2012-08-31 11:19:48 -07:00
Dima Kogan
83379b0280 renamed POD file. README.pod is now a symlink 2012-08-31 11:19:48 -07:00
Dima Kogan
aa690c92e4 removed the POD from the script. Its main home is now in feedgnuplot.POD 2012-08-31 11:13:29 -07:00
Dima Kogan
2b2a40f1fe version bump 2012-08-31 01:36:23 -07:00
Dima Kogan
dd034797ec updated completions with the new options 2012-08-31 01:35:16 -07:00
Dima Kogan
c89ddef9ba POD update 2012-08-31 01:25:13 -07:00
Dima Kogan
f4859ae475 --extracmds, --histogram, --y2 can now take comma-separated lists 2012-08-31 01:24:49 -07:00
Dima Kogan
69c635103a generic terminals can now be requested 2012-08-31 01:05:58 -07:00
Dima Kogan
8952973ba2 added histogram support 2012-08-31 00:51:08 -07:00
Dima Kogan
e14b57b6ad no longer hardcoding 'x11' as the default terminal 2012-07-24 17:38:22 -07:00
Dima Kogan
7141538258 POD update 2012-02-11 21:05:33 -08:00
Dima Kogan
970364289d changelog bump 2012-02-11 21:05:07 -08:00
Dima Kogan
e8e54edd9d made consistent my email addy in the debian changelog 2012-02-11 21:03:53 -08:00
Dima Kogan
e30f0c792e added --geometry option to specify plot dimensions 2012-02-11 20:48:22 -08:00
Dima Kogan
7d7374e628 version bump 2011-12-27 16:48:13 -08:00
Dima Kogan
7559ed5f66 data-ids can now include characters such as -. Any non-whitespace works 2011-12-27 16:46:30 -08:00
20 changed files with 642 additions and 802 deletions

70
Changes Normal file
View File

@@ -0,0 +1,70 @@
feedgnuplot (1.22)
* removed --size option
-- Dima Kogan <dima@secretsauce.net> Mon, 03 Sep 2012 08:33:26 -0700
feedgnuplot (1.21)
* removed the POD from the script to its own file
* fixed regression to allow no given extracmds, histogram or y2
options
-- Dima Kogan <dima@secretsauce.net> Sun, 02 Sep 2012 23:52:21 -0700
feedgnuplot (1.20)
* no longer hardcoding 'x11' as the default terminal
* added histogram support
* generic terminals can now be requested
* --extracmds, --histogram, --y2 can now take comma-separated lists
-- Dima Kogan <dima@secretsauce.net> Fri, 31 Aug 2012 01:35:50 -0700
feedgnuplot (1.19)
* added --geometry option to specify plot dimensions
-- Dima Kogan <dima@secretsauce.net> Sat, 11 Feb 2012 21:04:42 -0800
feedgnuplot (1.18)
* data-ids can now include characters such as -. Any non-whitespace
works
-- Dima Kogan <dima@secretsauce.net> Tue, 27 Dec 2011 16:47:36 -0800
feedgnuplot (1.17)
[ Dima Kogan ]
* POD: removed -Winteractive, since this was apparently a mawk-ism
* added zsh and bash completions
[ Hermann Schwarting ]
* add build dependency libtest-script-run-perl
-- Dima Kogan <dima@secretsauce.net> Sun, 20 Nov 2011 19:17:22 -0800
feedgnuplot (1.16)
* Some POD fixes
-- Dima Kogan <dima@secretsauce.net> Fri, 11 Nov 2011 00:10:18 -0800
feedgnuplot (1.15)
* Renamed main script from feedGnuplot to feedgnuplot
-- Dima Kogan <dima@secretsauce.net> Sun, 16 Oct 2011 11:58:15 -0700
feedgnuplot (1.14)
* added 'clear' command, documented commands
-- Dima Kogan <dima@secretsauce.net> Sun, 22 May 2011 15:25:28 -0700
feedgnuplot (1.13)
* Better streaming plot control
-- Dima Kogan <dima@secretsauce.net> Tue, 26 Apr 2011 14:24:09 -0700

View File

@@ -1,8 +1,9 @@
If running on a Debian-based OS (this includes Ubuntu), it is highly recommended If running on a Debian-based OS (this includes Ubuntu), it is highly recommended
to install this program as a package by doing to install this program as a package by doing
ln -fs package_definitions/debian debian
dpkg-buildpackage -us -uc -b dpkg-buildpackage -us -uc -b
sudo dpkg -i feedgnuplot*.deb sudo dpkg -i ../feedgnuplot*.deb
This builds a debian package and installs it. This builds a debian package and installs it.

8
LICENSE Normal file
View File

@@ -0,0 +1,8 @@
This library is distributed under the terms of the GNU GPL:
http://www.gnu.org/licenses/gpl.html
or the Artistic license:
http://dev.perl.org/licenses/artistic.html

View File

@@ -1,5 +1,8 @@
Makefile.PL Makefile.PL
MANIFEST MANIFEST
bin/feedgnuplot bin/feedgnuplot
bin/feedgnuplot.pod
t/00-load.t t/00-load.t
t/manifest.t t/manifest.t
Changes
LICENSE

View File

@@ -4,14 +4,14 @@ use ExtUtils::MakeMaker;
sub parseversion sub parseversion
{ {
# grab the version number from the debian changelog file. I look for lines line # grab the version number from the changelog. I look for lines line
# #
# libpackage-perl (0.02) unstable; urgency=low # libpackage-perl (0.02)
# #
# I parse out the 0.02 part # I parse out the 0.02 part
open DCH, 'debian/changelog' or die "Couldn't open debian/changelog"; open DCH, 'Changes' or die "Couldn't open 'Changes'";
my ($version) = <DCH> =~ /^\S+ \s* \( ([0-9\.]+) \)/x my ($version) = <DCH> =~ /^\S+ \s* \( ([0-9\.]+) \)/x
or die "Couldn't parse version from debian/changelog"; or die "Couldn't parse version from 'Changes'";
close DCH; close DCH;
return $version; return $version;
@@ -23,37 +23,33 @@ sub MY::libscan
my ($self, $file) = @_; my ($self, $file) = @_;
# Don't install the README.pod or any non-feedgnuplot .pl file # Don't install any symlinks (i.e. README.pod)
return undef if $file !~ /feedgnuplot.pl/ && $file =~ /\.pl$|^README.pod/; return undef if -l $file;
return $self->SUPER::libscan ($file); return $self->SUPER::libscan ($file);
} }
# I want my manpage to go into the man section '1', NOT '1p'. Here I add a
# snippet to the end of the generated Makefile to force this
sub MY::postamble
{
return "MAN1EXT := 1\n";
}
WriteMakefile WriteMakefile
( (
NAME => 'feedgnuplot', NAME => 'feedgnuplot',
AUTHOR => q{Dima Kogan <dima@secretsauce.net>}, AUTHOR => q{Dima Kogan <dima@secretsauce.net>},
VERSION => parseversion(), VERSION => parseversion(),
ABSTRACT_FROM => 'bin/feedgnuplot', ABSTRACT_FROM => 'bin/feedgnuplot.pod',
($ExtUtils::MakeMaker::VERSION >= 6.3002 ($ExtUtils::MakeMaker::VERSION >= 6.3002
? ('LICENSE' => 'perl') ? ('LICENSE' => 'perl')
: ()), : ()),
PL_FILES => {}, PL_FILES => {},
EXE_FILES => [ 'bin/feedgnuplot' ], EXE_FILES => [ 'bin/feedgnuplot' ],
MAN1PODS => { 'bin/feedgnuplot.pod' => 'blib/man1/feedgnuplot.1' },
PREREQ_PM => { 'Test::Script::Run' => 0}, PREREQ_PM => { 'Test::Script::Run' => 0},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'feedgnuplot-*' }, clean => { FILES => 'feedgnuplot-*' },
); );
# reroute the main POD into a separate README.pod if requested. This is here
# purely to generate a README.pod for the github front page
if(exists $ARGV[0] && $ARGV[0] eq '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 (<SCRIPT>)
{
if (/^=/../^=cut/)
{ print README; }
}
}

View File

@@ -1,364 +0,0 @@
=head1 NAME
feedgnuplot - 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 0 "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 |
gawk '/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<awk> command generates some data to
plot and the C<feedgnuplot> reads it in from STDIN and generates the plot. The
C<awk> invocation is just an example; more interesting things would be plotted
in normal usage. No 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 passed
in. To add arbitrary curve styles, use C<--curvestyle curveID extrastyle>. Pass
these more than once to affect more than one curve. To apply an extra style to
I<all> 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 original example above (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<X>-value for the rest of the data on that line. Without
C<--domain> the I<X>-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 original
example above produces 2 curves, with B<1,2,3,4,5> as the I<X>-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<X>-values. As many points as
desired can appear on a single line, but all points on a line are associated
with the I<X>-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<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 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<and> 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<Z> as a function of I<X> and I<Y>
instead of I<Y> as a function of I<X>). 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.
=head3 Special data commands
Other than the raw data, 2 special commands are interpreted if they appear in
the input. These are C<replot> and C<clear>. If a line of data begins with
C<replot> and we're plotting in realtime with C<--stream>, the plot will be
refreshed immediately. If a line of data begins with C<clear>, the plot is
cleared, to be re-filled with any data following the C<clear>.
=head2 Real-time streaming data
To plot real-time data, pass in the C<--stream [refreshperiod]> option. Data
will then be plotted as it is received. The plot will be updated every
C<refreshperiod> seconds. If the period isn't specified, a 1Hz refresh rate is
used. To refresh at specific intervals indicated by the data, set the
refreshperiod to 0 or to 'trigger'. The plot will then I<only> be refreshed when
a data line 'replot' is received. This 'replot' command works in both triggered
and timed modes, but in triggered mode, it's the only way to replot.
To plot only the most recent data (instead of I<all> the data), C<--xlen
windowsize> can be given. This will create an constantly-updating, scrolling
view of the recent past. C<windowsize> 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 enable self-plotting data files. There are 2 ways of
doing this: with a shebang (#!) or with inline perl data.
=head3 Self-plotting data with a #!
A self-plotting, executable data file C<data> 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.
=head3 Self-plotting data with perl inline data
Perl supports storing data and code in the same file. This can also be used to
create self-plotting files:
$ cat plotdata.pl
#!/usr/bin/perl
use strict;
use warnings;
open PLOT, "| feedgnuplot --lines --points" or die "Couldn't open plotting pipe";
while( <DATA> )
{
my @xy = split;
print PLOT "@xy\n";
}
__DATA__
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 especially useful if the logged data is not in a format directly
supported by feedgnuplot. Raw data can be stored after the __DATA__ directive,
with a small perl script to manipulate the data into a useable format and send
it to the plotter.
=head1 ARGUMENTS
--[no]domain If enabled, the first element of each line is the
domain variable. If not, the point index is used
--[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 --nodataid' would parse the 4 numbers as points in 4
different curves at x=3
'--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 --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 --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 ID 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 xy plot. Requires extra data for the color.
zmin/zmax can be used to set the extents of the colors.
Automatically increments extraValuesPerPoint
--stream [period] Plot the data as it comes in, in realtime. If period is given,
replot every period seconds. If no period is given, replot at
1Hz. If the period is given as 0 or 'trigger', replot ONLY when
the incoming data dictates this . See the "Real-time streaming
data" section of the man page.
--[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
--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
--legend curveID legend
Set the label for a curve plot. Use this option multiple times
for multiple curves. With --dataid, curveID is the ID. Otherwise,
it's the index of the curve, starting at 0
--autolegend Use the curve IDs for the legend. Titles given with --legend
override these
--xlen xxx When using --stream, sets the size of the x-window to plot.
Omit this or set it to 0 to plot ALL the data. Does not
make sense with 3d plots. Implies --monotonic
--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. 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 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.
Does not apply to 3d plots.
--curvestyle curveID style
Additional styles per curve. With --dataid, curveID is the
ID. Otherwise, it's the index of the curve, starting at 0. Use
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
--size xxx Gnuplot size option
--square Plot data with aspect ratio 1. For 3D plots, this controls the
aspect ratio for all 3 axes
--square_xy For 3D plots, set square aspect ratio for ONLY the x,y axes
--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 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
--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. 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)
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.
=head1 ACKNOWLEDGEMENT
This program is originally based on the driveGnuPlots.pl script from
Thanassis Tsiodras. It is available from his site at
L<http://users.softlab.ece.ntua.gr/~ttsiod/gnuplotStreaming.html>
=head1 REPOSITORY
L<https://github.com/dkogan/feedgnuplot>
=head1 AUTHOR
Dima Kogan, C<< <dima@secretsauce.net> >>
=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

1
README.pod Symbolic link
View File

@@ -0,0 +1 @@
bin/feedgnuplot.pod

View File

@@ -89,20 +89,26 @@ sub interpretCommandline
# do not stream in the data by default # do not stream in the data by default
# point plotting by default. # point plotting by default.
# no monotonicity checks by default # no monotonicity checks by default
# normal histograms by default
$options{ maxcurves } = 100; $options{ maxcurves } = 100;
$options{ histstyle} = 'freq';
# Previously I was using 'legend=s%' and 'curvestyle=s%' for curve addressing. This had cleaner # Previously I was using 'legend=s%' and 'curvestyle=s%' for curve addressing. This had cleaner
# syntax, but disregarded the order of the given options. This resulted in arbitrarily ordered # syntax, but disregarded the order of the given options. This resulted in arbitrarily ordered
# curves. # curves.
# needed for these to be parsed into a ref to a list # needed for these to be parsed into a ref to a list
$options{legend} = []; $options{legend} = [];
$options{curvestyle} = []; $options{curvestyle} = [];
$options{histogram} = [];
GetOptions($options, 'stream:s', 'domain!', 'dataid!', '3d!', 'colormap!', 'lines!', 'points!', GetOptions($options, 'stream:s', 'domain!', 'dataid!', '3d!', 'colormap!', 'lines!', 'points!',
'circles', 'legend=s{2}', 'autolegend!', 'xlabel=s', 'ylabel=s', 'y2label=s', 'zlabel=s', 'circles', 'legend=s{2}', 'autolegend!', 'xlabel=s', 'ylabel=s', 'y2label=s', 'zlabel=s',
'title=s', 'xlen=f', 'ymin=f', 'ymax=f', 'xmin=f', 'xmax=f', 'y2min=f', 'y2max=f', 'title=s', 'xlen=f', 'ymin=f', 'ymax=f', 'xmin=f', 'xmax=f', 'y2min=f', 'y2max=f',
'zmin=f', 'zmax=f', 'y2=s@', 'curvestyle=s{2}', 'curvestyleall=s', 'extracmds=s@', 'zmin=f', 'zmax=f', 'y2=s@', 'curvestyle=s{2}', 'curvestyleall=s', 'extracmds=s@',
'size=s', 'square!', 'square_xy!', 'hardcopy=s', 'maxcurves=i', 'monotonic!', 'square!', 'square_xy!', 'hardcopy=s', 'maxcurves=i', 'monotonic!',
'extraValuesPerPoint=i', 'help', 'dump') or pod2usage(1); 'histogram=s@', 'binwidth=f', 'histstyle=s',
'terminal=s',
'extraValuesPerPoint=i', 'help', 'dump',
'geometry=s') or pod2usage(1);
# handle various cmdline-option errors # handle various cmdline-option errors
if ( $options->{help} ) if ( $options->{help} )
@@ -111,6 +117,13 @@ sub interpretCommandline
# no global style if one isn't given # no global style if one isn't given
$options->{curvestyleall} = '' unless defined $options->{curvestyleall}; $options->{curvestyleall} = '' unless defined $options->{curvestyleall};
# expand options that are given as comma-separated lists
for my $listkey (qw(extracmds histogram y2))
{
@{$options{$listkey}} = map split('\s*,\s*', $_), @{$options{$listkey}}
if defined $options{$listkey};
}
# parse stream option. Allowed only numbers >= 0 or 'trigger' # parse stream option. Allowed only numbers >= 0 or 'trigger'
if(defined $options->{stream}) if(defined $options->{stream})
{ {
@@ -176,6 +189,12 @@ sub interpretCommandline
print STDERR "--3d does not make sense with --monotonic\n"; print STDERR "--3d does not make sense with --monotonic\n";
exit -1; exit -1;
} }
if ( defined $options->{binwidth} || @{$options->{histogram}} )
{
print STDERR "--3d does not make sense with histograms\n";
exit -1;
}
} }
else else
{ {
@@ -203,6 +222,12 @@ sub interpretCommandline
# --xlen implies an order to the data, so I force monotonicity # --xlen implies an order to the data, so I force monotonicity
$options{monotonic} = 1 if defined $options{xlen}; $options{monotonic} = 1 if defined $options{xlen};
if( $options{histstyle} !~ /freq|cum|uniq|cnorm/ )
{
print STDERR "unknown histstyle. Allowed are 'freq...', 'cum...', 'uniq...', 'cnorm...'\n";
exit -1;
}
} }
sub getGnuplotVersion sub getGnuplotVersion
@@ -252,7 +277,9 @@ sub mainThread
} }
else else
{ {
open PIPE, "|gnuplot $dopersist" or die "Can't initialize gnuplot\n"; my $geometry = defined $options{geometry} ?
"-geometry $options{geometry}" : '';
open PIPE, "|gnuplot $geometry $dopersist" or die "Can't initialize gnuplot\n";
} }
autoflush PIPE 1; autoflush PIPE 1;
@@ -261,22 +288,25 @@ sub mainThread
if( $options{hardcopy}) if( $options{hardcopy})
{ {
$outputfile = $options{hardcopy}; $outputfile = $options{hardcopy};
($outputfileType) = $outputfile =~ /\.(eps|ps|pdf|png)$/; $outputfile =~ /\.(eps|ps|pdf|png|svg)$/i;
if(!$outputfileType) { die("Only .eps, .ps, .pdf and .png supported\n"); } $outputfileType = $1 ? lc $1 : '';
my %terminalOpts = my %terminalOpts =
( eps => 'postscript solid color enhanced eps', ( eps => 'postscript solid color enhanced eps',
ps => 'postscript solid color landscape 10', ps => 'postscript solid color landscape 10',
pdf => 'pdfcairo solid color font ",10" size 11in,8.5in', pdf => 'pdfcairo solid color font ",10" size 11in,8.5in',
png => 'png size 1280,1024' ); png => 'png size 1280,1024',
svg => 'svg');
print PIPE "set terminal $terminalOpts{$outputfileType}\n"; $options{terminal} ||= $terminalOpts{$outputfileType}
print PIPE "set output \"$outputfile\"\n"; if $terminalOpts{$outputfileType};
}
else die "Asked to plot to file '$outputfile', but I don't know which terminal to use, and no --terminal given"
{ unless $options{terminal};
print PIPE "set terminal x11\n";
} }
print PIPE "set terminal $options{terminal}\n" if $options{terminal};
print PIPE "set output \"$outputfile\"\n" if $outputfile;
# If a bound isn't given I want to set it to the empty string, so I can communicate it simply to # If a bound isn't given I want to set it to the empty string, so I can communicate it simply to
# gnuplot # gnuplot
@@ -325,15 +355,13 @@ sub mainThread
# set a square aspect ratio. Gnuplot does this differently for 2D and 3D plots # set a square aspect ratio. Gnuplot does this differently for 2D and 3D plots
if(! $options{'3d'}) if(! $options{'3d'})
{ {
$options{size} = '' unless defined $options{size}; print(PIPE "set size ratio -1\n");
$options{size} .= ' ratio -1';
} }
else else
{ {
print(PIPE "set view equal xyz\n"); print(PIPE "set view equal xyz\n");
} }
} }
print(PIPE "set size $options{size}\n") if defined $options{size};
if($options{square_xy}) if($options{square_xy})
{ {
@@ -384,11 +412,21 @@ sub mainThread
} }
} }
# set up histograms
$options{binwidth} ||= 1; # if no binwidth given, set it to 1
print PIPE
"set boxwidth $options{binwidth}\n" .
"histbin(x) = $options{binwidth} * floor(0.5 + x/$options{binwidth})\n";
foreach (@{$options{histogram}})
{
setCurveAsHistogram( $_ );
}
# regexp for a possibly floating point, possibly scientific notation number # regexp for a possibly floating point, possibly scientific notation number
my $numRE = '-?\d*\.?\d+(?:[Ee][-+]?\d+)?'; my $numRE = '-?\d*\.?\d+(?:[Ee][-+]?\d+)?';
# a point may be preceded by an id # a point may be preceded by an id
my $pointRE = $options{dataid} ? '(\w+)\s+' : '()'; my $pointRE = $options{dataid} ? '(\S+)\s+' : '()';
$pointRE .= '(' . join('\s+', ($numRE) x $valuesPerPoint) . ')'; $pointRE .= '(' . join('\s+', ($numRE) x $valuesPerPoint) . ')';
$pointRE = qr/$pointRE/; $pointRE = qr/$pointRE/;
@@ -561,7 +599,9 @@ sub updateCurveOptions
my $titleoption = defined $title ? "title \"$title\"" : "notitle"; my $titleoption = defined $title ? "title \"$title\"" : "notitle";
my $extraoption = defined $options{curvestyleall} ? $options{curvestyleall} : ''; my $extraoption = defined $options{curvestyleall} ? $options{curvestyleall} : '';
$curveoptions->{options} = "$titleoption $curveoptions->{extraoptions} $extraoption"; my $histoptions = $curveoptions->{histoptions} || '';
$curveoptions->{options} = "$histoptions $titleoption $curveoptions->{extraoptions} $extraoption";
} }
sub getCurve sub getCurve
@@ -606,6 +646,16 @@ sub setCurveLabel
updateCurveOptions($curve->[0], $id); updateCurveOptions($curve->[0], $id);
} }
sub setCurveAsHistogram
{
my ($id, $str) = @_;
my $curve = getCurve($id);
$curve->[0]{histoptions} = 'using (histbin($2)):(1.0) smooth ' . $options{histstyle};
updateCurveOptions($curve->[0], $id);
}
# remove all the curve data # remove all the curve data
sub clearCurves sub clearCurves
{ {
@@ -619,370 +669,3 @@ sub pushPoint
my ($curve, $xy) = @_; my ($curve, $xy) = @_;
push @$curve, $xy; push @$curve, $xy;
} }
__END__
=head1 NAME
feedgnuplot - 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 0 "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 |
gawk '/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<awk> command generates some data to
plot and the C<feedgnuplot> reads it in from STDIN and generates the plot. The
C<awk> invocation is just an example; more interesting things would be plotted
in normal usage. No 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 passed
in. To add arbitrary curve styles, use C<--curvestyle curveID extrastyle>. Pass
these more than once to affect more than one curve. To apply an extra style to
I<all> 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 original example above (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<X>-value for the rest of the data on that line. Without
C<--domain> the I<X>-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 original
example above produces 2 curves, with B<1,2,3,4,5> as the I<X>-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<X>-values. As many points as
desired can appear on a single line, but all points on a line are associated
with the I<X>-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<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 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<and> 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<Z> as a function of I<X> and I<Y>
instead of I<Y> as a function of I<X>). 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.
=head3 Special data commands
Other than the raw data, 2 special commands are interpreted if they appear in
the input. These are C<replot> and C<clear>. If a line of data begins with
C<replot> and we're plotting in realtime with C<--stream>, the plot will be
refreshed immediately. If a line of data begins with C<clear>, the plot is
cleared, to be re-filled with any data following the C<clear>.
=head2 Real-time streaming data
To plot real-time data, pass in the C<--stream [refreshperiod]> option. Data
will then be plotted as it is received. The plot will be updated every
C<refreshperiod> seconds. If the period isn't specified, a 1Hz refresh rate is
used. To refresh at specific intervals indicated by the data, set the
refreshperiod to 0 or to 'trigger'. The plot will then I<only> be refreshed when
a data line 'replot' is received. This 'replot' command works in both triggered
and timed modes, but in triggered mode, it's the only way to replot.
To plot only the most recent data (instead of I<all> the data), C<--xlen
windowsize> can be given. This will create an constantly-updating, scrolling
view of the recent past. C<windowsize> 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 enable self-plotting data files. There are 2 ways of
doing this: with a shebang (#!) or with inline perl data.
=head3 Self-plotting data with a #!
A self-plotting, executable data file C<data> 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.
=head3 Self-plotting data with perl inline data
Perl supports storing data and code in the same file. This can also be used to
create self-plotting files:
$ cat plotdata.pl
#!/usr/bin/perl
use strict;
use warnings;
open PLOT, "| feedgnuplot --lines --points" or die "Couldn't open plotting pipe";
while( <DATA> )
{
my @xy = split;
print PLOT "@xy\n";
}
__DATA__
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 especially useful if the logged data is not in a format directly
supported by feedgnuplot. Raw data can be stored after the __DATA__ directive,
with a small perl script to manipulate the data into a useable format and send
it to the plotter.
=head1 ARGUMENTS
--[no]domain If enabled, the first element of each line is the
domain variable. If not, the point index is used
--[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 --nodataid' would parse the 4 numbers as points in 4
different curves at x=3
'--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 --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 --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 ID 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 xy plot. Requires extra data for the color.
zmin/zmax can be used to set the extents of the colors.
Automatically increments extraValuesPerPoint
--stream [period] Plot the data as it comes in, in realtime. If period is given,
replot every period seconds. If no period is given, replot at
1Hz. If the period is given as 0 or 'trigger', replot ONLY when
the incoming data dictates this . See the "Real-time streaming
data" section of the man page.
--[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
--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
--legend curveID legend
Set the label for a curve plot. Use this option multiple times
for multiple curves. With --dataid, curveID is the ID. Otherwise,
it's the index of the curve, starting at 0
--autolegend Use the curve IDs for the legend. Titles given with --legend
override these
--xlen xxx When using --stream, sets the size of the x-window to plot.
Omit this or set it to 0 to plot ALL the data. Does not
make sense with 3d plots. Implies --monotonic
--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. 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 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.
Does not apply to 3d plots.
--curvestyle curveID style
Additional styles per curve. With --dataid, curveID is the
ID. Otherwise, it's the index of the curve, starting at 0. Use
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
--size xxx Gnuplot size option
--square Plot data with aspect ratio 1. For 3D plots, this controls the
aspect ratio for all 3 axes
--square_xy For 3D plots, set square aspect ratio for ONLY the x,y axes
--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 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
--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. 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)
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.
=head1 ACKNOWLEDGEMENT
This program is originally based on the driveGnuPlots.pl script from
Thanassis Tsiodras. It is available from his site at
L<http://users.softlab.ece.ntua.gr/~ttsiod/gnuplotStreaming.html>
=head1 REPOSITORY
L<https://github.com/dkogan/feedgnuplot>
=head1 AUTHOR
Dima Kogan, C<< <dima@secretsauce.net> >>
=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

394
bin/feedgnuplot.pod Normal file
View File

@@ -0,0 +1,394 @@
=head1 NAME
feedgnuplot - 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 0 "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 |
gawk '/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<awk> command generates some data to
plot and the C<feedgnuplot> reads it in from STDIN and generates the plot. The
C<awk> invocation is just an example; more interesting things would be plotted
in normal usage. No 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 passed
in. To add arbitrary curve styles, use C<--curvestyle curveID extrastyle>. Pass
these more than once to affect more than one curve. To apply an extra style to
I<all> 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 original example above (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<X>-value for the rest of the data on that line. Without
C<--domain> the I<X>-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 original
example above produces 2 curves, with B<1,2,3,4,5> as the I<X>-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<X>-values. As many points as
desired can appear on a single line, but all points on a line are associated
with the I<X>-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<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 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<and> 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<Z> as a function of I<X> and I<Y>
instead of I<Y> as a function of I<X>). 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.
=head3 Special data commands
Other than the raw data, 2 special commands are interpreted if they appear in
the input. These are C<replot> and C<clear>. If a line of data begins with
C<replot> and we're plotting in realtime with C<--stream>, the plot will be
refreshed immediately. If a line of data begins with C<clear>, the plot is
cleared, to be re-filled with any data following the C<clear>.
=head2 Real-time streaming data
To plot real-time data, pass in the C<--stream [refreshperiod]> option. Data
will then be plotted as it is received. The plot will be updated every
C<refreshperiod> seconds. If the period isn't specified, a 1Hz refresh rate is
used. To refresh at specific intervals indicated by the data, set the
refreshperiod to 0 or to 'trigger'. The plot will then I<only> be refreshed when
a data line 'replot' is received. This 'replot' command works in both triggered
and timed modes, but in triggered mode, it's the only way to replot.
To plot only the most recent data (instead of I<all> the data), C<--xlen
windowsize> can be given. This will create an constantly-updating, scrolling
view of the recent past. C<windowsize> 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 can be inferred from the filename, if B<.ps>, B<.eps>, B<.pdf>,
B<.svg> or B<.png> is requested. If any other file type is requested,
C<--terminal> I<must> be passed in to tell gnuplot how to make the plot.
=head2 Self-plotting data files
This script can be used to enable self-plotting data files. There are 2 ways of
doing this: with a shebang (#!) or with inline perl data.
=head3 Self-plotting data with a #!
A self-plotting, executable data file C<data> 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.
=head3 Self-plotting data with perl inline data
Perl supports storing data and code in the same file. This can also be used to
create self-plotting files:
$ cat plotdata.pl
#!/usr/bin/perl
use strict;
use warnings;
open PLOT, "| feedgnuplot --lines --points" or die "Couldn't open plotting pipe";
while( <DATA> )
{
my @xy = split;
print PLOT "@xy\n";
}
__DATA__
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 especially useful if the logged data is not in a format directly
supported by feedgnuplot. Raw data can be stored after the __DATA__ directive,
with a small perl script to manipulate the data into a useable format and send
it to the plotter.
=head1 ARGUMENTS
--[no]domain If enabled, the first element of each line is the
domain variable. If not, the point index is used
--[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 --nodataid' would parse the 4 numbers as points in 4
different curves at x=3
'--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 --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 --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 ID 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 xy plot. Requires extra data for the color.
zmin/zmax can be used to set the extents of the colors.
Automatically increments extraValuesPerPoint
--stream [period] Plot the data as it comes in, in realtime. If period is given,
replot every period seconds. If no period is given, replot at
1Hz. If the period is given as 0 or 'trigger', replot ONLY when
the incoming data dictates this . See the "Real-time streaming
data" section of the man page.
--[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
--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
--legend curveID legend
Set the label for a curve plot. Use this option multiple times
for multiple curves. With --dataid, curveID is the ID. Otherwise,
it's the index of the curve, starting at 0
--autolegend Use the curve IDs for the legend. Titles given with --legend
override these
--xlen xxx When using --stream, sets the size of the x-window to plot.
Omit this or set it to 0 to plot ALL the data. Does not
make sense with 3d plots. Implies --monotonic
--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. 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 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.
Does not apply to 3d plots. Can be passed multiple times, or passed a
comma-separated list
--histogram curveID
Set up a this specific curve to plot a histogram. The bin
width is given with the --binwidth option (assumed 1.0 if
omitted). --histogram does NOT touch the drawing style.
It is often desired to plot these with boxes, and this
MUST be explicitly requested with --curvestyleall 'with
boxes'. This works with --domain and/or --stream, but in
those cases the x-value is used ONLY to cull old data
because of --xlen or --monotonic. I.e. the x-values are
NOT drawn in any way. Can be passed multiple times, or passed a comma-
separated list
--binwidth width The width of bins when making histograms. This setting applies to ALL
histograms in the plot. Defaults to 1.0 if not given.
--histstyle style Normally, histograms are generated with the 'smooth freq'
gnuplot style. --histstyle can be used to select
different 'smooth' settings. Allowed are 'unique',
'cumulative' and 'cnormal'. 'unique' indicates whether a
bin has at least one item in it: instead of counting the
items, it'll always report 0 or 1. 'cumulative' is the
integral of the "normal" histogram. 'cnormal' is like
'cumulative', but rescaled to end up at 1.0.
--curvestyle curveID style
Additional styles per curve. With --dataid, curveID is the
ID. Otherwise, it's the index of the curve, starting at 0. Use
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. Can be passed multiple times, or passed a comma-
separated list
--square Plot data with aspect ratio 1. For 3D plots, this controls the
aspect ratio for all 3 axes
--square_xy For 3D plots, set square aspect ratio for ONLY the x,y axes
--hardcopy xxx If not streaming, output to a file specified here. Format
inferred from filename, unless specified by --terminal
--terminal xxx String passed to 'set terminal'. No attempts are made to
validate this. --hardcopy sets this to some sensible
defaults if --hardcopy is given .png, .pdf, .ps, .eps or
.svg. If any other file type is desired, use both
--hardcopy and --terminal
--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
--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. 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)
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.
--geometry If using X11, specifies the size, position of the plot window
=head1 ACKNOWLEDGEMENT
This program is originally based on the driveGnuPlots.pl script from
Thanassis Tsiodras. It is available from his site at
L<http://users.softlab.ece.ntua.gr/~ttsiod/gnuplotStreaming.html>
=head1 REPOSITORY
L<https://github.com/dkogan/feedgnuplot>
=head1 AUTHOR
Dima Kogan, C<< <dima@secretsauce.net> >>
=head1 LICENSE AND COPYRIGHT
Copyright 2011-2012 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

View File

@@ -27,7 +27,6 @@ complete -W \
--y2 \ --y2 \
--curvestyleall \ --curvestyleall \
--extracmds \ --extracmds \
--size \
--square \ --square \
--square_xy \ --square_xy \
--hardcopy \ --hardcopy \
@@ -35,5 +34,10 @@ complete -W \
--monotonic \ --monotonic \
--extraValuesPerPoint \ --extraValuesPerPoint \
--dump \ --dump \
--geometry \
--curvestyle \ --curvestyle \
--histogram \
--binwidth \
--histstyle \
--terminal \
--legend' feedgnuplot --legend' feedgnuplot

View File

@@ -3,7 +3,7 @@
_arguments -S \ _arguments -S \
'()--domain[first element of each line is the domain variable]' \ '()--domain[first element of each line is the domain variable]' \
'--dataid[each data point is preceded by the corresponding ID]' \ '--dataid[each data point is preceded by the corresponding ID]' \
'(--monotonic --xlen)--3d' \ '(--monotonic --xlen --histogram)--3d' \
'--colormap[show a colormapped xy plot]' \ '--colormap[show a colormapped xy plot]' \
'--stream[Plot the data in realtime]::period in s:' \ '--stream[Plot the data in realtime]::period in s:' \
'--lines' \ '--lines' \
@@ -28,7 +28,6 @@ _arguments -S
'*--y2:plot to place on the Y2 axis:' \ '*--y2:plot to place on the Y2 axis:' \
'--curvestyleall[Additional styles for ALL curves]:' \ '--curvestyleall[Additional styles for ALL curves]:' \
'*--extracmds[Additional gnuplot commands]:' \ '*--extracmds[Additional gnuplot commands]:' \
'--size[Gnuplot size option]:' \
'--square[Plot data with square aspect ratio]' \ '--square[Plot data with square aspect ratio]' \
'--square_xy[For 3D plots, set square aspect ratio for ONLY the x,y axes]' \ '--square_xy[For 3D plots, set square aspect ratio for ONLY the x,y axes]' \
'--hardcopy[Plot to a file]:' \ '--hardcopy[Plot to a file]:' \
@@ -36,5 +35,10 @@ _arguments -S
'(--3d)--monotonic[Resets plot if an X in the past is seen]' \ '(--3d)--monotonic[Resets plot if an X in the past is seen]' \
'--extraValuesPerPoint[How many extra values are given for each data point]:' \ '--extraValuesPerPoint[How many extra values are given for each data point]:' \
'--dump[Instead of printing to gnuplot, print to STDOUT]' \ '--dump[Instead of printing to gnuplot, print to STDOUT]' \
'--geometry[The X11 geometry string]:geometry string:' \
'*--curvestyle[Additional styles for a curve]:curve id: :style:' \ '*--curvestyle[Additional styles for a curve]:curve id: :style:' \
'(--3d)*--histogram:plot to treat as a histogram:' \
'--binwidth:Histogram bin width:' \
'--histstyle:Style of histogram:(frequency unique cumulative cnormal)' \
'--terminal:Terminal options to set with "set terminal":' \
'*--legend[Legend for a curve]:curve id: :legend:' '*--legend[Legend for a curve]:curve id: :legend:'

17
debian/control vendored
View File

@@ -1,17 +0,0 @@
Source: feedgnuplot
Section: perl
Priority: optional
Build-Depends: debhelper (>= 7), libtest-script-run-perl
Build-Depends-Indep: perl
Maintainer: Dima Kogan <dima@secretsauce.net>
Standards-Version: 3.9.2
Homepage: https://github.com/dkogan/feedgnuplot
Package: feedgnuplot
Architecture: all
Depends: ${misc:Depends}, ${perl:Depends}, gnuplot
Description: A pipe-oriented frontend to Gnuplot
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.

2
debian/watch vendored
View File

@@ -1,2 +0,0 @@
version=3
http://search.cpan.org/dist/feedGnuplot/ .*/feedgnuplot-v?(\d[\d.-]+)\.(?:tar(?:\.gz|\.bz2)?|tgz|zip)$

View File

@@ -1,3 +1,46 @@
feedgnuplot (1.23) unstable; urgency=low
* debian packaging cleanup
* package now uploaded to Debian (Closes: #686413)
-- Dima Kogan <dima@secretsauce.net> Mon, 10 Sep 2012 20:47:40 -0700
feedgnuplot (1.22) unstable; urgency=low
* removed --size option
-- Dima Kogan <dima@secretsauce.net> Mon, 03 Sep 2012 08:33:26 -0700
feedgnuplot (1.21) unstable; urgency=low
* removed the POD from the script to its own file
* fixed regression to allow no given extracmds, histogram or y2
options
-- Dima Kogan <dima@secretsauce.net> Sun, 02 Sep 2012 23:52:21 -0700
feedgnuplot (1.20) unstable; urgency=low
* no longer hardcoding 'x11' as the default terminal
* added histogram support
* generic terminals can now be requested
* --extracmds, --histogram, --y2 can now take comma-separated lists
-- Dima Kogan <dima@secretsauce.net> Fri, 31 Aug 2012 01:35:50 -0700
feedgnuplot (1.19) unstable; urgency=low
* added --geometry option to specify plot dimensions
-- Dima Kogan <dima@secretsauce.net> Sat, 11 Feb 2012 21:04:42 -0800
feedgnuplot (1.18) unstable; urgency=low
* data-ids can now include characters such as -. Any non-whitespace
works
-- Dima Kogan <dima@secretsauce.net> Tue, 27 Dec 2011 16:47:36 -0800
feedgnuplot (1.17) unstable; urgency=low feedgnuplot (1.17) unstable; urgency=low
[ Dima Kogan ] [ Dima Kogan ]
@@ -7,7 +50,7 @@ feedgnuplot (1.17) unstable; urgency=low
[ Hermann Schwarting ] [ Hermann Schwarting ]
* add build dependency libtest-script-run-perl * add build dependency libtest-script-run-perl
-- Dima Kogan <dkogan@secretsauce.net> Sun, 20 Nov 2011 19:17:22 -0800 -- Dima Kogan <dima@secretsauce.net> Sun, 20 Nov 2011 19:17:22 -0800
feedgnuplot (1.16) unstable; urgency=low feedgnuplot (1.16) unstable; urgency=low

View File

@@ -0,0 +1,20 @@
Source: feedgnuplot
Section: science
Priority: extra
Build-Depends: debhelper (>= 7), libtest-script-run-perl, perl
Maintainer: Dima Kogan <dima@secretsauce.net>
Uploaders: Dima Kogan <dima@secretsauce.net>
Standards-Version: 3.9.3
Homepage: https://github.com/dkogan/feedgnuplot
Vcs-Git: git://github.com/dkogan/feedgnuplot.git
Vcs-Browser: https://github.com/dkogan/feedgnuplot
DM-Upload-Allowed: yes
Package: feedgnuplot
Architecture: all
Depends: ${misc:Depends}, ${perl:Depends}, gnuplot
Description: Pipe-oriented frontend to Gnuplot
Flexible, command-line-oriented frontend to Gnuplot. 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.

View File

@@ -1,13 +1,9 @@
Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Maintainer: Dima Kogan, <dima at secretsauce.net> Source: https://github.com/dkogan/feedgnuplot
Source: http://search.cpan.org/dist/feedGnuplot/ Upstream-Contact: Dima Kogan, <dima@secretsauce.net>
Name: feedgnuplot Upstream-Name: feedgnuplot
Files: * Files: *
Copyright: Dima Kogan, <dima at secretsauce.net>
License:
Files: debian/*
Copyright: 2011, Dima Kogan <dima@secretsauce.net> Copyright: 2011, Dima Kogan <dima@secretsauce.net>
License: Artistic or GPL-1+ License: Artistic or GPL-1+