Compare commits

...

17 Commits

Author SHA1 Message Date
Dima Kogan
4958bda912 version bump 2016-10-15 20:50:58 -07:00
Dima Kogan
3860d8281b version bump 2016-10-15 20:42:27 -07:00
Dima Kogan
4f9adb6e11 histograms have the correct default style 2016-10-15 20:35:48 -07:00
Dima Kogan
167e85d2a7 minor simplification
I delete the with option after I use it. This is defensive and clarifies the
intent
2016-10-15 20:17:08 -07:00
Dima Kogan
5123ca73d3 minor simplification
I delete the style and styleall options after I use them. This is defensive and
clarifies the intent
2016-10-15 20:14:33 -07:00
Dima Kogan
d4ca90e1bd minor simplification
curvestyle_hash doesn't really exist anymore
2016-10-15 20:08:24 -07:00
Dima Kogan
9e669044c7 can now ask for fnormal histograms 2016-09-08 23:02:31 -07:00
Dima Kogan
cacbedb336 added sample rpm spec file 2016-07-27 23:08:22 -07:00
Dima Kogan
18994e68e1 version bump 2016-07-27 22:16:34 -07:00
Dima Kogan
f8ed461571 No enhanced text mode in hardcopies, slightly larger font size 2016-07-11 10:11:06 -07:00
Dima Kogan
f01431dd1e removed unneeded old code 2016-01-22 00:48:59 -08:00
Dima Kogan
80b6030996 version bump 2016-01-01 08:11:45 -08:00
Dima Kogan
232b68b819 At the end of a streaming plot, include the last chunk of data 2016-01-01 08:08:51 -08:00
Dima Kogan
12eb829f16 whitespace 2015-12-15 13:18:29 -08:00
Dima Kogan
80b5d0ab61 improved documentation of --histstyle 2015-12-15 13:18:23 -08:00
Dima Kogan
960c43e758 added --equation to the completions 2015-11-13 11:23:15 -08:00
Dima Kogan
2ecdfb9aef minor POD fix 2015-11-13 11:19:25 -08:00
5 changed files with 149 additions and 73 deletions

21
Changes
View File

@@ -1,3 +1,24 @@
feedgnuplot (1.39)
* by default, histograms are plotted in expected ways
-- Dima Kogan <dima@secretsauce.net> Sat, 15 Oct 2016 20:45:15 -0700
feedgnuplot (1.38)
* hardcopy defaults:
- no enhanced text mode
- larger font size
-- Dima Kogan <dima@secretsauce.net> Wed, 27 Jul 2016 22:15:11 -0700
feedgnuplot (1.37)
* At the end of a streaming plot, include the last chunk of data
* Added --equation to the completions
-- Dima Kogan <dima@secretsauce.net> Fri, 01 Jan 2016 08:09:43 -0800
feedgnuplot (1.36) feedgnuplot (1.36)
* Added --equation to plot symbolic equations * Added --equation to plot symbolic equations

View File

@@ -8,13 +8,13 @@ use Getopt::Long;
use Time::HiRes qw( usleep gettimeofday tv_interval ); use Time::HiRes qw( usleep gettimeofday tv_interval );
use IO::Handle; use IO::Handle;
use IO::Select; use IO::Select;
use List::Util qw( first ); use List::Util qw( first any );
use Scalar::Util qw( looks_like_number ); use Scalar::Util qw( looks_like_number );
use Text::ParseWords; # for shellwords use Text::ParseWords; # for shellwords
use Pod::Usage; use Pod::Usage;
use Time::Piece; use Time::Piece;
my $VERSION = 1.36; my $VERSION = 1.39;
my %options; my %options;
interpretCommandline(); interpretCommandline();
@@ -138,17 +138,41 @@ sub interpretCommandline
# --curvestyleall, so fill that in # --curvestyleall, so fill that in
if( $options{styleall} ) if( $options{styleall} )
{ {
if($options{curvestyleall} ) if($options{curvestyleall} ) { $options{curvestyleall} .= " $options{styleall}"; }
{ else { $options{curvestyleall} = $options{styleall}; }
$options{curvestyleall} .= " $options{styleall}"; delete $options{styleall};
} }
else
{
$options{curvestyleall} = $options{styleall};
}
}
push @{$options{curvestyle}}, @{$options{style}};
push @{$options{curvestyle}}, @{$options{style}};
delete $options{style};
if( $options{curvestyleall} && $options{with} )
{
print STDERR "--curvestyleall and --with are mutually exclusive. Please just use one.\n";
exit -1;
}
if( $options{with} )
{
$options{curvestyleall} = "with $options{with}";
delete $options{with};
}
# If we're plotting histograms, then set the default histogram options for
# each histogram curve
#
# Apply this to plain (non-cumulative) histograms
if( !$options{curvestyleall} && $options{histstyle} =~ /freq|fnorm/ )
{
for my $hist_curve(@{$options{histogram}})
{
# If we don't specify any options specifically for this histogram, use
# the defaults: filled boxes with borders
if( !any { $options{curvestyle}[$_*2] eq $hist_curve } 0..(@{$options{curvestyle}}/2 - 1) )
{
push @{$options{curvestyle}}, ($hist_curve, 'with boxes fill solid border lt -1');
}
}
}
# --legend and --curvestyle options are conceptually hashes, but are parsed as # --legend and --curvestyle options are conceptually hashes, but are parsed as
# arrays in order to preserve the ordering. I parse both of these into hashes # arrays in order to preserve the ordering. I parse both of these into hashes
@@ -231,17 +255,6 @@ sub interpretCommandline
} }
} }
if( $options{curvestyleall} && $options{with} )
{
print STDERR "--curvestyleall and --with are mutually exclusive. Please just use one.\n";
exit -1;
}
if( $options{with} )
{
$options{curvestyleall} = "with $options{with}";
$options{with} = '';
}
if ($options{colormap}) if ($options{colormap})
{ {
# colormap styles all curves with palette. Seems like there should be a way to do this with a # colormap styles all curves with palette. Seems like there should be a way to do this with a
@@ -333,9 +346,9 @@ 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/ ) if( $options{histstyle} !~ /freq|cum|uniq|cnorm|fnorm/ )
{ {
print STDERR "unknown histstyle. Allowed are 'freq...', 'cum...', 'uniq...', 'cnorm...'\n"; print STDERR "unknown histstyle. Allowed are 'freq...', 'fnorm...', 'cum...', 'uniq...', 'cnorm...'\n";
exit -1; exit -1;
} }
@@ -497,11 +510,11 @@ sub mainThread
} }
my %terminalOpts = my %terminalOpts =
( eps => 'postscript solid color enhanced eps', ( eps => 'postscript noenhanced solid color enhanced eps',
ps => 'postscript solid color landscape 10', ps => 'postscript noenhanced solid color landscape 12',
pdf => 'pdfcairo solid color font ",10" size 11in,8.5in', pdf => 'pdfcairo noenhanced solid color font ",12" size 11in,8.5in',
png => 'png size 1280,1024', png => 'png noenhanced size 1280,1024',
svg => 'svg'); svg => 'svg noenhanced');
if( !defined $options{terminal} && if( !defined $options{terminal} &&
defined $outputfileType && defined $outputfileType &&
@@ -552,7 +565,7 @@ sub mainThread
print(PIPE "set view equal xy\n"); print(PIPE "set view equal xy\n");
} }
# For the specified values, set the legend entries to 'title "blah blah"' # For the specified values, set the legend entries to 'title "blah blah"'
if(@{$options{legend}}) if(@{$options{legend}})
{ {
# @{$options{legend}} is a list where consecutive pairs are (curveID, # @{$options{legend}} is a list where consecutive pairs are (curveID,
@@ -567,13 +580,11 @@ sub mainThread
} }
} }
# add the extra curve options # add the extra curve options
if(@{$options{curvestyle}}) if(@{$options{curvestyle}})
{ {
# @{$options{curvestyle}} is a list where consecutive pairs are (curveID, # @{$options{curvestyle}} is a list where consecutive pairs are (curveID,
# style). I use $options{curvestyle} here instead of # style).
# $options{curvestyle_hash} because I create a new curve when I see a new
# one, and the hash is unordered, thus messing up the ordering
my $n = scalar @{$options{curvestyle}}/2; my $n = scalar @{$options{curvestyle}}/2;
foreach my $idx (0..$n-1) foreach my $idx (0..$n-1)
{ {
@@ -582,22 +593,22 @@ sub mainThread
} }
} }
# For the values requested to be printed on the y2 axis, set that # For the values requested to be printed on the y2 axis, set that
addCurveOption($_, 'axes x1y2') foreach (@{$options{y2}}); addCurveOption($_, 'axes x1y2') foreach (@{$options{y2}});
# timefmt # timefmt
if( $options{timefmt} ) if( $options{timefmt} )
{ {
print(PIPE "set timefmt '$options{timefmt}'\n"); print(PIPE "set timefmt '$options{timefmt}'\n");
print(PIPE "set xdata time\n"); print(PIPE "set xdata time\n");
} }
# add the extra global options # add the extra global options
print(PIPE "$_\n") foreach (@{$options{extracmds}}); print(PIPE "$_\n") foreach (@{$options{extracmds}});
print(PIPE "set $_\n") foreach (@{$options{set}}); print(PIPE "set $_\n") foreach (@{$options{set}});
print(PIPE "unset $_\n") foreach (@{$options{unset}}); print(PIPE "unset $_\n") foreach (@{$options{unset}});
# set up histograms # set up histograms
$options{binwidth} ||= 1; # if no binwidth given, set it to 1 $options{binwidth} ||= 1; # if no binwidth given, set it to 1
print PIPE print PIPE
"set boxwidth $options{binwidth}\n" . "set boxwidth $options{binwidth}\n" .
@@ -605,11 +616,6 @@ sub mainThread
setCurveAsHistogram( $_ ) foreach (@{$options{histogram}}); setCurveAsHistogram( $_ ) foreach (@{$options{histogram}});
# set all the axis ranges
# If a bound isn't given I want to set it to the empty string, so I can communicate it simply to
# gnuplot
print PIPE "set xtics\n";
if(@{$options{y2}}) if(@{$options{y2}})
{ {
print PIPE "set ytics nomirror\n"; print PIPE "set ytics nomirror\n";
@@ -749,7 +755,7 @@ sub mainThread
} }
# finished reading in all. Plot what we have # finished reading in all. Plot what we have
plotStoredData() unless $options{stream}; plotStoredData() unless $options{stream} && $options{exit};
if ( defined $options{hardcopy}) if ( defined $options{hardcopy})
{ {
@@ -851,19 +857,6 @@ sub updateCurveOptions
{ $title = $id; } { $title = $id; }
my $titleoption = defined $title ? "title \"$title\"" : "notitle"; my $titleoption = defined $title ? "title \"$title\"" : "notitle";
my ($curvestyleall);
if( defined $options{curvestyle_hash}{$id} )
{
# I have a curve-specific style set with --curvestyle. This style lives in
# $curve->{extraoptions}, and it overrides the global styles
$curvestyleall = '';
}
else
{
$curvestyleall = $options{curvestyleall};
}
my $histoptions = $curve->{histoptions} || ''; my $histoptions = $curve->{histoptions} || '';
my $usingoptions = ''; my $usingoptions = '';
@@ -884,7 +877,7 @@ sub updateCurveOptions
$usingoptions = "using 1:" . join(':', @rest); $usingoptions = "using 1:" . join(':', @rest);
} }
$curve->{options} = "$histoptions $usingoptions $titleoption $curve->{extraoptions} $curvestyleall"; $curve->{options} = "$histoptions $usingoptions $titleoption $curve->{extraoptions} $options{curvestyleall}";
} }
sub getCurve sub getCurve
@@ -1521,11 +1514,11 @@ passing something like
C<--histogram curveID> C<--histogram curveID>
Set up a this specific curve to plot a histogram. The bin width is given with Set up a this specific curve to plot a histogram. The bin width is given with
the C<--binwidth> option (assumed 1.0 if omitted). C<--histogram> does I<not> the C<--binwidth> option (assumed 1.0 if omitted). If a drawing style is not
touch the drawing style. It is often desired to plot these with boxes, and this specified for this curve (C<--curvestyle>) or all curves (C<--with>,
I<must> be explicitly requested by C<--with boxes>. This works with C<--domain> C<--curvestyleall>) then the default histogram style is set: filled boxes with
borders. This is what the user generally wants. This works with C<--domain>
and/or C<--stream>, but in those cases the x-value is used I<only> to cull old and/or C<--stream>, but in those cases the x-value is used I<only> to cull old
data because of C<--xlen> or C<--monotonic>. I.e. the x-values are I<not> drawn data because of C<--xlen> or C<--monotonic>. I.e. the x-values are I<not> drawn
in any way. Can be passed multiple times, or passed a comma- separated list in any way. Can be passed multiple times, or passed a comma- separated list
@@ -1541,12 +1534,14 @@ in the plot. Defaults to 1.0 if not given.
C<--histstyle style> C<--histstyle style>
Normally, histograms are generated with the 'smooth freq' gnuplot style. Normally, histograms are generated with the 'smooth frequency' gnuplot style.
C<--histstyle> can be used to select different 'smooth' settings. Allowed are C<--histstyle> can be used to select different C<smooth> settings (see the
'unique', 'cumulative' and 'cnormal'. 'unique' indicates whether a bin has at gnuplot C<help smooth> page for more info). Allowed values are 'frequency' (the
least one item in it: instead of counting the items, it'll always report 0 or 1. default), 'fnormal' (available in very recent gnuplots), 'unique', 'cumulative'
'cumulative' is the integral of the "normal" histogram. 'cnormal' is like and 'cnormal'. 'fnormal' is a normalized histogram. 'unique' indicates whether a
'cumulative', but rescaled to end up at 1.0. 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 'frequency' histogram.
'cnormal' is like 'cumulative', but rescaled to end up at 1.0.
=item =item
@@ -1617,7 +1612,7 @@ times.
C<--equation xxx> C<--equation xxx>
Gnuplot can plot both data and symbolic equations. C<feedgnuplot> generally Gnuplot can plot both data and symbolic equations. C<feedgnuplot> generally
plots data, but with this option can plot symbolic equations /also/. This is plots data, but with this option can plot symbolic equations I<also>. This is
generally intended to augment data plots, since for equation-only plots you generally intended to augment data plots, since for equation-only plots you
don't need C<feedgnuplot>. C<--equation> can be passed multiple times for don't need C<feedgnuplot>. C<--equation> can be passed multiple times for
multiple equations. The given strings are passed to gnuplot directly without any multiple equations. The given strings are passed to gnuplot directly without any
@@ -1629,7 +1624,7 @@ basic example:
--equation 'sin(x)/x' --equation 'cos(x)/x with lines lw 4' --equation 'sin(x)/x' --equation 'cos(x)/x with lines lw 4'
Here I plot the incoming data (points along a line) with the given style (a line Here I plot the incoming data (points along a line) with the given style (a line
with thickness 3), /and/ I plot two damped sinusoids on the same plot. The with thickness 3), I<and> I plot two damped sinusoids on the same plot. The
sinusoids are not affected by C<feedgnuplot> styling, so their styles are set sinusoids are not affected by C<feedgnuplot> styling, so their styles are set
separately, as in this example. More complicated example: separately, as in this example. More complicated example:
@@ -1638,7 +1633,7 @@ separately, as in this example. More complicated example:
--set parametric --set "trange [0:2*3.14]" --equation "sin(t),cos(t)" --set parametric --set "trange [0:2*3.14]" --equation "sin(t),cos(t)"
Here the data I generate is points along the unit circle. I plot these as Here the data I generate is points along the unit circle. I plot these as
points, and I /also/ plot a true circle as a parametric equation. points, and I I<also> plot a true circle as a parametric equation.
=item =item
@@ -1857,8 +1852,8 @@ in a Thinkpad.
=head2 Plotting a histogram of file sizes in a directory, granular to 10MB =head2 Plotting a histogram of file sizes in a directory, granular to 10MB
$ ls -l | awk '{print $5/1e6}' | $ ls -l | awk '{print $5/1e6}' |
feedgnuplot --histogram 0 --with boxes feedgnuplot --histogram 0
--binwidth 10 --set 'style fill solid' --binwidth 10
--ymin 0 --xlabel 'File size (MB)' --ylabel Frequency --ymin 0 --xlabel 'File size (MB)' --ylabel Frequency
=head1 ACKNOWLEDGEMENT =head1 ACKNOWLEDGEMENT

View File

@@ -20,6 +20,7 @@ complete -W \
--extracmds \ --extracmds \
--set \ --set \
--unset \ --unset \
--equation \
--geometry \ --geometry \
--hardcopy \ --hardcopy \
--help \ --help \

View File

@@ -32,6 +32,7 @@ _arguments -S
'*--extracmds[Additional gnuplot commands]:command' \ '*--extracmds[Additional gnuplot commands]:command' \
'*--set[Additional 'set' gnuplot commands]:set-option' \ '*--set[Additional 'set' gnuplot commands]:set-option' \
'*--unset[Additional 'unset' gnuplot commands]:unset-option' \ '*--unset[Additional 'unset' gnuplot commands]:unset-option' \
'*--equation[Raw symbolic equation]:equation' \
'--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]:filename' \ '--hardcopy[Plot to a file]:filename' \

58
feedgnuplot.spec Normal file
View File

@@ -0,0 +1,58 @@
# Sample spec file for rpm-based systems. Debian-based systems already have this
# packaged, so we do not ship those here
Name: feedgnuplot
Version: 1.38
Release: 1%{?dist}
Summary: Pipe-oriented frontend to Gnuplot
BuildArch: noarch
License: Artistic or GPL-1+
URL: https://www.github.com/dkogan/feedgnuplot/
Source0: https://www.github.com/dkogan/feedgnuplot/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
BuildRequires: /usr/bin/pod2html
BuildRequires: perl-String-ShellQuote
BuildRequires: perl-ExtUtils-MakeMaker
BuildRequires: perl
BuildRequires: gawk
BuildRequires: gnuplot
BuildRequires: perl-IPC-Run
Requires: gnuplot
%description
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.
%prep
%setup -q
%build
perl Makefile.PL INSTALLDIRS=vendor
make
pod2html --title=feedgnuplot bin/feedgnuplot > feedgnuplot.html
%install
make install DESTDIR=%{buildroot} PREFIX=/usr
mkdir -p %{buildroot}%{_defaultdocdir}/%{name}
cp Changes LICENSE feedgnuplot.html %{buildroot}%{_defaultdocdir}/%{name}
mkdir -p %{buildroot}%{_datadir}/zsh/site-functions
cp completions/zsh/* %{buildroot}%{_datadir}/zsh/site-functions
mkdir -p %{buildroot}%{_datadir}/bash-completion/completions
cp completions/bash/* %{buildroot}%{_datadir}/bash-completion/completions
rm -rf %{buildroot}/usr/lib64
%files
%{_bindir}/*
%{_datadir}/zsh/*
%{_datadir}/bash-completion/*
%doc %{_defaultdocdir}/%{name}/*
%doc %{_mandir}