From 592ce20d1f9b96493088862aa9dea1423d94a1b6 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 8 Jan 2020 21:19:50 -0800 Subject: [PATCH 1/9] readme update github had a bug where it wouldn't render symlinks to embedded POD. Is this still broken? --- README.pod | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/README.pod b/README.pod index 9af43ab..f55bcd8 100644 --- a/README.pod +++ b/README.pod @@ -62,6 +62,7 @@ Simple plotting of piped data: 2 +-----------------------------------------------------------------+ 0 1 1.5 2 2.5 3 3.5 4 4.5 5 +Here we asked for ASCII plotting, which is useful for documentation. Simple real-time plotting example: plot how much data is received on the wlan0 network interface in bytes/second (uses bash, awk and Linux): @@ -524,10 +525,10 @@ plot I histograms or I I-histograms. =item -C<--xmin/xmax/ymin/ymax/y2min/y2max/zmin/zmax xxx> +C<--xmin/xmax/x2min/x2max/ymin/ymax/y2min/y2max/zmin/zmax xxx> Set the range for the given axis. These x-axis bounds are ignored in a streaming -plot. The y2-axis bound do not apply in 3d plots. The z-axis bounds apply +plot. The x2/y2-axis bounds do not apply in 3d plots. The z-axis bounds apply I to 3d plots or colormaps. Note that there is no C<--xrange> to set both sides at once or C<--xinv> to flip the axis around: anything more than the basics supported in this option is clearly obtainable by talking to gnuplot, for @@ -535,23 +536,29 @@ instance C<--set 'xrange [20:10]'> to set the given inverted bounds. =item -C<--xlabel/ylabel/y2label/zlabel xxx> +C<--xlabel/x2label/ylabel/y2label/zlabel xxx> -Label the given axis. The y2-axis label does not apply to 3d plots while the +Label the given axis. The x2/y2-axis labels do not apply to 3d plots while the z-axis label applies I to 3d plots. =item -C<--y2 xxx> +C<--x2/--y2/--x1y2/--x2y1/--x2y2 xxx> -Plot the data specified by this curve ID on the y2 axis. Without C<--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. By default the y2-axis -curves look the same as the y-axis ones. I.e. the viewer of the resulting plot -has to be told which is which via an axes label, legend, etc. Prior to version -1.25 of feedgnuplot the curves plotted on the y2 axis were drawn with a thicker -line. This is no longer the case, but that behavior can be brought back by -passing something like +By default data is plotted against the x1 and y1 axes (the left and bottom one +respectively). If we want a particular curve plotted against a different axis, +we can specify that with these options. You pass C<--AXIS ID> where C +defines the axis (C or C or C or C or C) and the C +is the curve ID. C<--x2> is a synonym for C<--x2y1> and C<--y2> is a synonym for +C<--x1y2>. The curve ID is an ordered 0-based index or a specific ID if +C<--dataid> or C<--vnlog>. None of these apply to 3d plots. Can be passed +multiple times for different curve IDs, multiple IDs can be passed in as a +comma-separated list. By default the curves plotted against the various axes +aren not drawn in any differentiated way: the viewer of the resulting plot has +to be told which is which via an axes label, legend, colors, etc. Prior to +version 1.25 of C the curves plotted on the y2 axis were drawn with +a thicker line. This is no longer the case, but that behavior can be brought +back by passing something like --y2 curveid --style curveid 'linewidth 3' From 5e0869dc2531abecf6d76081f7abebaa0805ec86 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 24 Jan 2020 19:24:02 -0800 Subject: [PATCH 2/9] Added support for --every and --everyall Needs documentation, tab completion --- bin/feedgnuplot | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/bin/feedgnuplot b/bin/feedgnuplot index b5672ed..4cdeebf 100755 --- a/bin/feedgnuplot +++ b/bin/feedgnuplot @@ -90,6 +90,7 @@ sub interpretCommandline $options{legend} = []; $options{curvestyle} = []; $options{style} = []; + $options{every} = []; $options{histogram} = []; $options{x1y2} = []; $options{x2y1} = []; @@ -114,6 +115,7 @@ sub interpretCommandline 'zmin=f', 'zmax=f', 'x2=s@', 'y2=s@', 'x1y2=s@', 'x2y1=s@', 'x2y2=s@', 'style=s{2}', 'curvestyle=s{2}', 'curvestyleall=s', 'styleall=s', 'with=s', 'extracmds=s@', 'set=s@', 'unset=s@', + 'every=s{2}', 'everyall=s', 'square!', 'square_xy!', 'square-xy!', 'squarexy!', 'hardcopy=s', 'maxcurves=i', 'monotonic!', 'timefmt=s', 'equation=s@', 'image=s', @@ -178,7 +180,7 @@ sub interpretCommandline @{$options{$listkey}} = map split('\s*,\s*', $_), @{$options{$listkey}} if defined $options{$listkey}; } - for my $listkey (qw(curvestyle rangesize tuplesize)) + for my $listkey (qw(curvestyle rangesize tuplesize every)) { next unless defined $options{$listkey}; my @in = @{$options{$listkey}}; @@ -253,7 +255,7 @@ sub interpretCommandline # arrays in order to preserve the ordering. I parse both of these into hashes # because those are useful to have later. After this I can access individual # legends with $options{legend_hash}{curveid} - for my $listkey (qw(legend curvestyle rangesize)) + for my $listkey (qw(legend curvestyle rangesize every)) { $options{"${listkey}_hash"} = {}; @@ -812,6 +814,17 @@ sub mainThread $options{curvestyle}[$idx*2 + 1]); } } + if(@{$options{every}}) + { + # @{$options{every}} is a list where consecutive pairs are (curveID, + # every). + my $n = scalar @{$options{every}}/2; + foreach my $idx (0..$n-1) + { + addEveryOption($options{every}[$idx*2 ], + $options{every}[$idx*2 + 1]); + } + } addCurveOption($_, 'axes x1y2') foreach (@{$options{x1y2}}); addCurveOption($_, 'axes x2y1') foreach (@{$options{x2y1}}); @@ -1156,7 +1169,7 @@ sub updateCurveOptions } - $curve->{options} = "$histoptions $usingoptions $titleoption $curve->{extraoptions}"; + $curve->{options} = "$curve->{everyoptions} $histoptions $usingoptions $titleoption $curve->{extraoptions}"; } sub getCurve @@ -1180,6 +1193,9 @@ sub getCurve extraoptions => (!exists $options{curvestyle_hash}{$id} && exists $options{curvestyleall}) ? "$options{curvestyleall} " : ' ', + everyoptions => (!exists $options{every_hash}{$id} && + exists $options{everyall}) ? + "every $options{everyall} " : ' ', datastring => '', datastring_meta => [], datastring_offset => 0}; # push a curve with no data and no options @@ -1214,6 +1230,14 @@ sub addCurveOption $curve->{extraoptions} .= "$str "; updateCurveOptions($curve, $id); } +sub addEveryOption +{ + my ($id, $str) = @_; + + my $curve = getCurve($id); + $curve->{everyoptions} .= "every $str "; + updateCurveOptions($curve, $id); +} sub setCurveLabel { From 2f9a6acdb31fb4954c6ad6a59ca22a6912d9999a Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 20 Oct 2019 18:57:11 -0700 Subject: [PATCH 3/9] Minor no-op refactoring The ID->curve hash %curveIndices is now called $curveFromID, and now gives you a curve reference, not an index to @curves I can thus reorder @curves as I like, and %curveFromID remains valid --- bin/feedgnuplot | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bin/feedgnuplot b/bin/feedgnuplot index 4cdeebf..8b1f482 100755 --- a/bin/feedgnuplot +++ b/bin/feedgnuplot @@ -31,8 +31,8 @@ interpretCommandline(); # datastring my @curves = (); -# list mapping curve names to their indices in the @curves list -my %curveIndices = (); +# Maps a curve ID to the corresponding curve +my %curveFromID = (); # Whether any new data has arrived since the last replot my $haveNewData; @@ -1186,7 +1186,7 @@ sub getCurve my ($id) = @_; - if( !exists $curveIndices{$id} ) + if( !exists $curveFromID{$id} ) { push @curves, {# if we have a catch-all style and no specific style, use # the catch-all style @@ -1199,9 +1199,9 @@ sub getCurve datastring => '', datastring_meta => [], datastring_offset => 0}; # push a curve with no data and no options - $curveIndices{$id} = $#curves; + $curveFromID{$id} = $curves[-1]; - updateCurveOptions($curves[$#curves], $id); + updateCurveOptions($curves[-1], $id); # --xlen has a meaning if we're not plotting histograms at all or if we're @@ -1218,8 +1218,11 @@ sub getCurve print STDERR "--xlen only makes sense when plotting ONLY histograms or ONLY NON-histograms\n"; exit -1; } + + return $curves[-1]; } - return $curves[$curveIndices{$id}]; + + return $curveFromID{$id}; } sub addCurveOption From e9c9ff02e491677724bc1c58d6578a46f8d12c3c Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 20 Oct 2019 19:33:27 -0700 Subject: [PATCH 4/9] Minor no-op refactoring --- bin/feedgnuplot | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/bin/feedgnuplot b/bin/feedgnuplot index 8b1f482..484fe5c 100755 --- a/bin/feedgnuplot +++ b/bin/feedgnuplot @@ -1188,20 +1188,21 @@ sub getCurve if( !exists $curveFromID{$id} ) { - push @curves, {# if we have a catch-all style and no specific style, use - # the catch-all style - extraoptions => (!exists $options{curvestyle_hash}{$id} && - exists $options{curvestyleall}) ? - "$options{curvestyleall} " : ' ', - everyoptions => (!exists $options{every_hash}{$id} && - exists $options{everyall}) ? - "every $options{everyall} " : ' ', - datastring => '', - datastring_meta => [], - datastring_offset => 0}; # push a curve with no data and no options - $curveFromID{$id} = $curves[-1]; + my $curve = {# if we have a catch-all style and no specific style, use + # the catch-all style + extraoptions => (!exists $options{curvestyle_hash}{$id} && + exists $options{curvestyleall}) ? + "$options{curvestyleall} " : ' ', + everyoptions => (!exists $options{every_hash}{$id} && + exists $options{everyall}) ? + "every $options{everyall} " : ' ', + datastring => '', + datastring_meta => [], + datastring_offset => 0}; # push a curve with no data and no options + push @curves, $curve; # push a curve with no data and no options + $curveFromID{$id} = $curve; - updateCurveOptions($curves[-1], $id); + updateCurveOptions($curve, $id); # --xlen has a meaning if we're not plotting histograms at all or if we're @@ -1219,7 +1220,7 @@ sub getCurve exit -1; } - return $curves[-1]; + return $curve; } return $curveFromID{$id}; From 7e1e6af184f217b7ec2629701ae984644279da3e Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sun, 20 Oct 2019 19:34:46 -0700 Subject: [PATCH 5/9] Removed reference to no-longer-existing variable --- bin/feedgnuplot | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bin/feedgnuplot b/bin/feedgnuplot index 484fe5c..f29bc48 100755 --- a/bin/feedgnuplot +++ b/bin/feedgnuplot @@ -1188,10 +1188,7 @@ sub getCurve if( !exists $curveFromID{$id} ) { - my $curve = {# if we have a catch-all style and no specific style, use - # the catch-all style - extraoptions => (!exists $options{curvestyle_hash}{$id} && - exists $options{curvestyleall}) ? + my $curve = {extraoptions => ( exists $options{curvestyleall}) ? "$options{curvestyleall} " : ' ', everyoptions => (!exists $options{every_hash}{$id} && exists $options{everyall}) ? From c4eef7a167316ca604bfc91508f1660254fd06da Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 17 Apr 2020 14:01:03 -0700 Subject: [PATCH 6/9] --timefmt can be used with --histogram --- bin/feedgnuplot | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/feedgnuplot b/bin/feedgnuplot index f29bc48..8ed1e7a 100755 --- a/bin/feedgnuplot +++ b/bin/feedgnuplot @@ -397,9 +397,9 @@ sub interpretCommandline } else { - if ( $options{timefmt} && !$options{domain} ) + if ( $options{timefmt} && !$options{domain} && !@{$options{histogram}} ) { - print STDERR "--timefmt makes sense only with --domain\n"; + print STDERR "--timefmt makes sense only with --domain or --histogram\n"; exit -1; } @@ -1002,8 +1002,8 @@ sub mainThread } else { - $domain[0] = $line_number; - $domain0_numeric = makeDomainNumeric( $domain[0] ); + $domain[0] = $line_number; + $domain0_numeric = $line_number; } my $id = -1; @@ -1156,7 +1156,7 @@ sub updateCurveOptions my $histoptions = $curve->{histoptions} || ''; my $usingoptions = ''; - if( $options{timefmt} ) + if( $options{timefmt} && !$histoptions ) { # with --timefmt I need an explicit 'using' specification. I specify the # columns as 1:2:3..... I need the right number of columns (this is given From 2e6c9d6ea3a6a557aea74f48f73e3ca211d623bf Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 17 Apr 2020 14:05:54 -0700 Subject: [PATCH 7/9] added tab completions for --every and --everyall --- completions/bash/feedgnuplot | 2 ++ completions/zsh/_feedgnuplot | 2 ++ 2 files changed, 4 insertions(+) diff --git a/completions/bash/feedgnuplot b/completions/bash/feedgnuplot index 9159551..e11bedf 100644 --- a/completions/bash/feedgnuplot +++ b/completions/bash/feedgnuplot @@ -9,6 +9,8 @@ complete -W \ --curvestyleall \ --style \ --styleall \ + --every \ + --everyall \ --with \ --dataid \ --domain \ diff --git a/completions/zsh/_feedgnuplot b/completions/zsh/_feedgnuplot index 5daa270..9d4c87c 100644 --- a/completions/zsh/_feedgnuplot +++ b/completions/zsh/_feedgnuplot @@ -54,6 +54,8 @@ _arguments -S '--geometry[The X11 geometry string]:geometry string:' \ '*--curvestyle[Additional styles for a curve]:curve id: :style:' \ '*--style[Additional styles for a curve]:curve id: :style:' \ + '*--every[Decimation factor for a curve]:curve id: :decimation factor:' \ + '--everyall[Decimation factor for ALL curves]:decimation factor' \ '(--3d)*--histogram:plot to treat as a histogram:' \ '--binwidth:Histogram bin width:' \ '--histstyle:Style of histogram:(frequency fnormal unique cumulative cnormal)' \ From 4e85f991c4a5eb4fa5b7e52ca4df82d7cc72d093 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 17 Apr 2020 14:07:08 -0700 Subject: [PATCH 8/9] version bump --- Changes | 7 +++++++ bin/feedgnuplot | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Changes b/Changes index 4ec0603..299d400 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,10 @@ +feedgnuplot (1.54) + + * Added --every and --everyall to decimate the input data + * --timefmt can be used with --histogram + + -- Dima Kogan Fri, 17 Apr 2020 14:06:55 -0700 + feedgnuplot (1.53) * Full support for all 4 axes. Added --x2... diff --git a/bin/feedgnuplot b/bin/feedgnuplot index 8ed1e7a..74668ef 100755 --- a/bin/feedgnuplot +++ b/bin/feedgnuplot @@ -16,7 +16,7 @@ use Pod::Usage; use Time::Piece; # Makefile.PL assumes this is in '' -my $VERSION = '1.53'; +my $VERSION = '1.54'; my %options; interpretCommandline(); From bdb9919c3938976df2910c859bb446dd88fd1706 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 17 Apr 2020 14:18:09 -0700 Subject: [PATCH 9/9] documented --every --- README.pod | 15 +++++++++++++++ bin/feedgnuplot | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/README.pod b/README.pod index f55bcd8..b134c3c 100644 --- a/README.pod +++ b/README.pod @@ -641,6 +641,21 @@ Exclusive with C<--styleall>. =item +C<--every curveID factor> + +Decimates the input. Instead of plotting every point in the given curve, plot +one point per factor. This is useful to quickly process huge datasets. For +instance, to plot 1% of the data, pass a factor of 100. + +=item + +C<--everyallID factor> + +Decimates the input. This works exactly like C<--every>, except it applies to +I the curves. + +=item + C<--extracmds xxx> Additional commands to pass on to gnuplot verbatim. These could contain extra diff --git a/bin/feedgnuplot b/bin/feedgnuplot index 74668ef..a876e63 100755 --- a/bin/feedgnuplot +++ b/bin/feedgnuplot @@ -1994,6 +1994,21 @@ Exclusive with C<--styleall>. =item +C<--every curveID factor> + +Decimates the input. Instead of plotting every point in the given curve, plot +one point per factor. This is useful to quickly process huge datasets. For +instance, to plot 1% of the data, pass a factor of 100. + +=item + +C<--everyallID factor> + +Decimates the input. This works exactly like C<--every>, except it applies to +I the curves. + +=item + C<--extracmds xxx> Additional commands to pass on to gnuplot verbatim. These could contain extra