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/README.pod b/README.pod index 9af43ab..b134c3c 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' @@ -634,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 b5672ed..a876e63 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(); @@ -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; @@ -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"} = {}; @@ -395,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; } @@ -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}}); @@ -989,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; @@ -1143,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 @@ -1156,7 +1169,7 @@ sub updateCurveOptions } - $curve->{options} = "$histoptions $usingoptions $titleoption $curve->{extraoptions}"; + $curve->{options} = "$curve->{everyoptions} $histoptions $usingoptions $titleoption $curve->{extraoptions}"; } sub getCurve @@ -1173,19 +1186,20 @@ 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 - extraoptions => (!exists $options{curvestyle_hash}{$id} && - exists $options{curvestyleall}) ? - "$options{curvestyleall} " : ' ', - datastring => '', - datastring_meta => [], - datastring_offset => 0}; # push a curve with no data and no options - $curveIndices{$id} = $#curves; + my $curve = {extraoptions => ( 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[$#curves], $id); + updateCurveOptions($curve, $id); # --xlen has a meaning if we're not plotting histograms at all or if we're @@ -1202,8 +1216,11 @@ sub getCurve print STDERR "--xlen only makes sense when plotting ONLY histograms or ONLY NON-histograms\n"; exit -1; } + + return $curve; } - return $curves[$curveIndices{$id}]; + + return $curveFromID{$id}; } sub addCurveOption @@ -1214,6 +1231,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 { @@ -1969,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 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)' \