mirror of
https://github.com/dkogan/feedgnuplot.git
synced 2025-05-05 22:11:12 +08:00
Real-time streaming plots now have an adjustable refresh rate, in addition to
data-triggered replotting
This commit is contained in:
parent
5d7701fb94
commit
f5c1e79ddc
27
README.pod
27
README.pod
@ -113,13 +113,19 @@ the same way as before.
|
|||||||
|
|
||||||
=head2 Real-time streaming data
|
=head2 Real-time streaming data
|
||||||
|
|
||||||
To plot real-time data, pass in the C<--stream> option. Data will then be
|
To plot real-time data, pass in the C<--stream [refreshperiod]> option. Data
|
||||||
plotted as it is received, with the refresh rate limited to 1Hz (currently
|
will then be plotted as it is received. The plot will be updated every
|
||||||
hard-coded). To plot only the most recent data (instead of I<all> the data),
|
C<refreshperiod> seconds. If the period isn't specified, a 1Hz refresh rate is
|
||||||
C<--xlen windowsize> can be given. This will create an constantly-updating,
|
used. To refresh at specific intervals indicated by the data set the
|
||||||
scrolling view of the recent past. C<windowsize> should be replaced by the
|
refreshperiod to 0 or to 'trigger'. The plot will then I<only> be refreshed when
|
||||||
desired length of the domain window to plot, in domain units (passed-in values
|
a data line 'replot' is received. This 'replot' command works in both triggered
|
||||||
if C<--domain> or line numbers otherwise).
|
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
|
=head2 Hardcopy output
|
||||||
|
|
||||||
@ -235,8 +241,11 @@ As an example, if line 3 of the input is "0 9 1 20"
|
|||||||
zmin/zmax can be used to set the extents of the colors.
|
zmin/zmax can be used to set the extents of the colors.
|
||||||
Automatically increments extraValuesPerPoint
|
Automatically increments extraValuesPerPoint
|
||||||
|
|
||||||
--[no]stream Do [not] display the data a point at a time, as it
|
--stream [period] Plot the data as it comes in, in realtime. If period is given,
|
||||||
comes in
|
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]lines Do [not] draw lines to connect consecutive points
|
||||||
--[no]points Do [not] draw points
|
--[no]points Do [not] draw points
|
||||||
|
@ -5,6 +5,7 @@ use Getopt::Long;
|
|||||||
use Time::HiRes qw( usleep );
|
use Time::HiRes qw( usleep );
|
||||||
use IO::Handle;
|
use IO::Handle;
|
||||||
use List::Util qw( first );
|
use List::Util qw( first );
|
||||||
|
use Scalar::Util qw( looks_like_number );
|
||||||
use Text::ParseWords;
|
use Text::ParseWords;
|
||||||
use threads;
|
use threads;
|
||||||
use threads::shared;
|
use threads::shared;
|
||||||
@ -41,7 +42,9 @@ if($options{stream})
|
|||||||
|
|
||||||
$dataQueue = Thread::Queue->new();
|
$dataQueue = Thread::Queue->new();
|
||||||
my $addThr = threads->create(\&mainThread);
|
my $addThr = threads->create(\&mainThread);
|
||||||
my $plotThr = threads->create(\&plotUpdateThread);
|
|
||||||
|
# spawn the plot updating thread. If I'm replotting from a data trigger, I don't need this
|
||||||
|
my $plotThr = threads->create(\&plotUpdateThread) unless $options{stream} < 0;
|
||||||
|
|
||||||
while(<>)
|
while(<>)
|
||||||
{
|
{
|
||||||
@ -59,7 +62,7 @@ if($options{stream})
|
|||||||
|
|
||||||
$streamingFinished = 1;
|
$streamingFinished = 1;
|
||||||
|
|
||||||
$plotThr->join();
|
$plotThr->join() if defined $plotThr;
|
||||||
$addThr->join();
|
$addThr->join();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -95,7 +98,7 @@ sub interpretCommandline
|
|||||||
# 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} = [];
|
||||||
GetOptions($options, 'stream!', '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@',
|
||||||
@ -106,8 +109,42 @@ sub interpretCommandline
|
|||||||
if ( $options->{help} )
|
if ( $options->{help} )
|
||||||
{ pod2usage(0); }
|
{ pod2usage(0); }
|
||||||
|
|
||||||
|
# no global style if one isn't given
|
||||||
$options->{curvestyleall} = '' unless defined $options->{curvestyleall};
|
$options->{curvestyleall} = '' unless defined $options->{curvestyleall};
|
||||||
|
|
||||||
|
# parse stream option. Allowed only numbers >= 0 or 'trigger'
|
||||||
|
if(defined $options->{stream})
|
||||||
|
{
|
||||||
|
if ( $options->{stream} eq '')
|
||||||
|
{
|
||||||
|
# if no streaming period is given, default to 1Hz.
|
||||||
|
$options->{stream} = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !looks_like_number $options->{stream} )
|
||||||
|
{
|
||||||
|
if($options->{stream} eq 'trigger')
|
||||||
|
{
|
||||||
|
$options->{stream} = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print STDERR "--stream can only take in values >=0 or 'trigger'\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $options->{stream} == 0 )
|
||||||
|
{
|
||||||
|
$options->{stream} = -1;
|
||||||
|
}
|
||||||
|
elsif ( $options->{stream} <= 0)
|
||||||
|
{
|
||||||
|
print STDERR "--stream can only take in values >=0 or 'trigger'\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -159,7 +196,7 @@ sub interpretCommandline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(defined $options{xlen} && !defined $options{stream} )
|
if(defined $options{xlen} && !$options{stream} )
|
||||||
{
|
{
|
||||||
print STDERR "--xlen does not make sense without --stream\n";
|
print STDERR "--xlen does not make sense without --stream\n";
|
||||||
exit -1;
|
exit -1;
|
||||||
@ -187,8 +224,8 @@ sub plotUpdateThread
|
|||||||
{
|
{
|
||||||
while(! $streamingFinished)
|
while(! $streamingFinished)
|
||||||
{
|
{
|
||||||
sleep(1);
|
usleep( $options{stream} * 1e6 );
|
||||||
$dataQueue->enqueue('Plot now');
|
$dataQueue->enqueue('replot');
|
||||||
}
|
}
|
||||||
|
|
||||||
$dataQueue->enqueue(undef);
|
$dataQueue->enqueue(undef);
|
||||||
@ -364,7 +401,7 @@ sub mainThread
|
|||||||
{
|
{
|
||||||
next if /^#/o;
|
next if /^#/o;
|
||||||
|
|
||||||
if($_ ne 'Plot now')
|
if($_ !~ /^replot/o)
|
||||||
{
|
{
|
||||||
# parse the incoming data lines. The format is
|
# parse the incoming data lines. The format is
|
||||||
# x id0 dat0 id1 dat1 ....
|
# x id0 dat0 id1 dat1 ....
|
||||||
@ -415,7 +452,7 @@ sub mainThread
|
|||||||
|
|
||||||
elsif($options{stream})
|
elsif($options{stream})
|
||||||
{
|
{
|
||||||
# only redraw a streaming plot if there's new data to plot
|
# we get here if we need to replot AND if we're streaming
|
||||||
next unless $haveNewData;
|
next unless $haveNewData;
|
||||||
$haveNewData = undef;
|
$haveNewData = undef;
|
||||||
|
|
||||||
@ -690,13 +727,19 @@ the same way as before.
|
|||||||
|
|
||||||
=head2 Real-time streaming data
|
=head2 Real-time streaming data
|
||||||
|
|
||||||
To plot real-time data, pass in the C<--stream> option. Data will then be
|
To plot real-time data, pass in the C<--stream [refreshperiod]> option. Data
|
||||||
plotted as it is received, with the refresh rate limited to 1Hz (currently
|
will then be plotted as it is received. The plot will be updated every
|
||||||
hard-coded). To plot only the most recent data (instead of I<all> the data),
|
C<refreshperiod> seconds. If the period isn't specified, a 1Hz refresh rate is
|
||||||
C<--xlen windowsize> can be given. This will create an constantly-updating,
|
used. To refresh at specific intervals indicated by the data set the
|
||||||
scrolling view of the recent past. C<windowsize> should be replaced by the
|
refreshperiod to 0 or to 'trigger'. The plot will then I<only> be refreshed when
|
||||||
desired length of the domain window to plot, in domain units (passed-in values
|
a data line 'replot' is received. This 'replot' command works in both triggered
|
||||||
if C<--domain> or line numbers otherwise).
|
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
|
=head2 Hardcopy output
|
||||||
|
|
||||||
@ -812,8 +855,11 @@ As an example, if line 3 of the input is "0 9 1 20"
|
|||||||
zmin/zmax can be used to set the extents of the colors.
|
zmin/zmax can be used to set the extents of the colors.
|
||||||
Automatically increments extraValuesPerPoint
|
Automatically increments extraValuesPerPoint
|
||||||
|
|
||||||
--[no]stream Do [not] display the data a point at a time, as it
|
--stream [period] Plot the data as it comes in, in realtime. If period is given,
|
||||||
comes in
|
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]lines Do [not] draw lines to connect consecutive points
|
||||||
--[no]points Do [not] draw points
|
--[no]points Do [not] draw points
|
||||||
|
Loading…
Reference in New Issue
Block a user