mirror of
https://github.com/dkogan/feedgnuplot.git
synced 2025-05-05 22:11:12 +08:00
1048 lines
46 KiB
Plaintext
1048 lines
46 KiB
Plaintext
.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35)
|
|
.\"
|
|
.\" Standard preamble:
|
|
.\" ========================================================================
|
|
.de Sp \" Vertical space (when we can't use .PP)
|
|
.if t .sp .5v
|
|
.if n .sp
|
|
..
|
|
.de Vb \" Begin verbatim text
|
|
.ft CW
|
|
.nf
|
|
.ne \\$1
|
|
..
|
|
.de Ve \" End verbatim text
|
|
.ft R
|
|
.fi
|
|
..
|
|
.\" Set up some character translations and predefined strings. \*(-- will
|
|
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
|
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
|
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
|
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
|
.\" nothing in troff, for use with C<>.
|
|
.tr \(*W-
|
|
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
|
.ie n \{\
|
|
. ds -- \(*W-
|
|
. ds PI pi
|
|
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
|
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
|
. ds L" ""
|
|
. ds R" ""
|
|
. ds C` ""
|
|
. ds C' ""
|
|
'br\}
|
|
.el\{\
|
|
. ds -- \|\(em\|
|
|
. ds PI \(*p
|
|
. ds L" ``
|
|
. ds R" ''
|
|
. ds C`
|
|
. ds C'
|
|
'br\}
|
|
.\"
|
|
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
|
.ie \n(.g .ds Aq \(aq
|
|
.el .ds Aq '
|
|
.\"
|
|
.\" If the F register is >0, we'll generate index entries on stderr for
|
|
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
|
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
|
.\" output yourself in some meaningful fashion.
|
|
.\"
|
|
.\" Avoid warning from groff about undefined register 'F'.
|
|
.de IX
|
|
..
|
|
.if !\nF .nr F 0
|
|
.if \nF>0 \{\
|
|
. de IX
|
|
. tm Index:\\$1\t\\n%\t"\\$2"
|
|
..
|
|
. if !\nF==2 \{\
|
|
. nr % 0
|
|
. nr F 2
|
|
. \}
|
|
.\}
|
|
.\"
|
|
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
|
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
|
. \" fudge factors for nroff and troff
|
|
.if n \{\
|
|
. ds #H 0
|
|
. ds #V .8m
|
|
. ds #F .3m
|
|
. ds #[ \f1
|
|
. ds #] \fP
|
|
.\}
|
|
.if t \{\
|
|
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
|
. ds #V .6m
|
|
. ds #F 0
|
|
. ds #[ \&
|
|
. ds #] \&
|
|
.\}
|
|
. \" simple accents for nroff and troff
|
|
.if n \{\
|
|
. ds ' \&
|
|
. ds ` \&
|
|
. ds ^ \&
|
|
. ds , \&
|
|
. ds ~ ~
|
|
. ds /
|
|
.\}
|
|
.if t \{\
|
|
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
|
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
|
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
|
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
|
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
|
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
|
.\}
|
|
. \" troff and (daisy-wheel) nroff accents
|
|
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
|
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
|
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
|
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
|
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
|
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
|
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
|
.ds ae a\h'-(\w'a'u*4/10)'e
|
|
.ds Ae A\h'-(\w'A'u*4/10)'E
|
|
. \" corrections for vroff
|
|
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
|
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
|
. \" for low resolution devices (crt and lpr)
|
|
.if \n(.H>23 .if \n(.V>19 \
|
|
\{\
|
|
. ds : e
|
|
. ds 8 ss
|
|
. ds o a
|
|
. ds d- d\h'-1'\(ga
|
|
. ds D- D\h'-1'\(hy
|
|
. ds th \o'bp'
|
|
. ds Th \o'LP'
|
|
. ds ae ae
|
|
. ds Ae AE
|
|
.\}
|
|
.rm #[ #] #H #V #F C
|
|
.\" ========================================================================
|
|
.\"
|
|
.IX Title "FEEDGNUPLOT 1"
|
|
.TH FEEDGNUPLOT 1 "2018-11-30" "perl v5.26.1" "User Contributed Perl Documentation"
|
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
|
.\" way too many mistakes in technical documents.
|
|
.if n .ad l
|
|
.nh
|
|
.SH "NAME"
|
|
feedgnuplot \- General purpose pipe\-oriented plotting tool
|
|
.SH "SYNOPSIS"
|
|
.IX Header "SYNOPSIS"
|
|
Simple plotting of piped data:
|
|
.PP
|
|
.Vb 6
|
|
\& $ seq 5 | awk \*(Aq{print 2*$1, $1*$1}\*(Aq
|
|
\& 2 1
|
|
\& 4 4
|
|
\& 6 9
|
|
\& 8 16
|
|
\& 10 25
|
|
\&
|
|
\& $ seq 5 | awk \*(Aq{print 2*$1, $1*$1}\*(Aq |
|
|
\& feedgnuplot \-\-lines \-\-points \-\-legend 0 "data 0" \-\-title "Test plot" \-\-y2 1
|
|
\& \-\-unset grid \-\-terminal \*(Aqdumb 80,40\*(Aq \-\-exit
|
|
\&
|
|
\& Test plot
|
|
\&
|
|
\& 10 +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ 25
|
|
\& | + + + + + + + *##|
|
|
\& | data 0 ***A*#* |
|
|
\& | ** # |
|
|
\& 9 |\-+ ** ## |
|
|
\& | ** # |
|
|
\& | ** # |
|
|
\& | ** ## +\-| 20
|
|
\& 8 |\-+ A # |
|
|
\& | ** # |
|
|
\& | ** ## |
|
|
\& | ** # |
|
|
\& | ** B |
|
|
\& 7 |\-+ ** ## |
|
|
\& | ** ## +\-| 15
|
|
\& | ** # |
|
|
\& | ** ## |
|
|
\& 6 |\-+ *A ## |
|
|
\& | ** ## |
|
|
\& | ** # |
|
|
\& | ** ## +\-| 10
|
|
\& 5 |\-+ ** ## |
|
|
\& | ** #B |
|
|
\& | ** ## |
|
|
\& | ** ## |
|
|
\& 4 |\-+ A ### |
|
|
\& | ** ## |
|
|
\& | ** ## +\-| 5
|
|
\& | ** ## |
|
|
\& | ** ##B# |
|
|
\& 3 |\-+ ** #### |
|
|
\& | **#### |
|
|
\& | #### |
|
|
\& |## + + + + + + + |
|
|
\& 2 +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ 0
|
|
\& 1 1.5 2 2.5 3 3.5 4 4.5 5
|
|
.Ve
|
|
.PP
|
|
Simple real-time plotting example: plot how much data is received on the wlan0
|
|
network interface in bytes/second (uses bash, awk and Linux):
|
|
.PP
|
|
.Vb 3
|
|
\& $ while true; do sleep 1; cat /proc/net/dev; done |
|
|
\& gawk \*(Aq/wlan0/ {if(b) {print $2\-b; fflush()} b=$2}\*(Aq |
|
|
\& feedgnuplot \-\-lines \-\-stream \-\-xlen 10 \-\-ylabel \*(AqBytes/sec\*(Aq \-\-xlabel seconds
|
|
.Ve
|
|
.SH "DESCRIPTION"
|
|
.IX Header "DESCRIPTION"
|
|
This is a flexible, command-line-oriented frontend to Gnuplot. It creates
|
|
plots from data coming in on \s-1STDIN\s0 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:
|
|
.PP
|
|
.Vb 1
|
|
\& $ seq 5 | awk \*(Aq{print 2*$1, $1*$1}\*(Aq | feedgnuplot
|
|
.Ve
|
|
.PP
|
|
You should see a plot with two curves. The \f(CW\*(C`awk\*(C'\fR command generates some data to
|
|
plot and the \f(CW\*(C`feedgnuplot\*(C'\fR reads it in from \s-1STDIN\s0 and generates the plot. The
|
|
\&\f(CW\*(C`awk\*(C'\fR 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.
|
|
.PP
|
|
The most commonly used functionality of gnuplot is supported directly by the
|
|
script. Anything not directly supported can still be done with options such as
|
|
\&\f(CW\*(C`\-\-set\*(C'\fR, \f(CW\*(C`\-\-extracmds\*(C'\fR \f(CW\*(C`\-\-style\*(C'\fR, etc. Arbitrary gnuplot commands can be
|
|
passed in with \f(CW\*(C`\-\-extracmds\*(C'\fR. For example, to turn off the grid, you can pass
|
|
in \f(CW\*(C`\-\-extracmds \*(Aqunset grid\*(Aq\*(C'\fR. Commands \f(CW\*(C`\-\-set\*(C'\fR and \f(CW\*(C`\-\-unset\*(C'\fR exists to
|
|
provide nicer syntax, so this is equivalent to passing \f(CW\*(C`\-\-unset grid\*(C'\fR. As many
|
|
of these options as needed can be passed in. To add arbitrary curve styles, use
|
|
\&\f(CW\*(C`\-\-style curveID extrastyle\*(C'\fR. Pass these more than once to affect more than one
|
|
curve.
|
|
.PP
|
|
To apply an extra style to \fIall\fR the curves that lack an explicit \f(CW\*(C`\-\-style\*(C'\fR,
|
|
pass in \f(CW\*(C`\-\-styleall extrastyle\*(C'\fR. In the most common case, the extra style is
|
|
\&\f(CW\*(C`with something\*(C'\fR. To support this more simply, you can pass in \f(CW\*(C`\-\-with
|
|
something\*(C'\fR instead of \f(CW\*(C`\-\-styleall \*(Aqwith something\*(Aq\*(C'\fR. \f(CW\*(C`\-\-styleall\*(C'\fR and
|
|
\&\f(CW\*(C`\-\-with\*(C'\fR are mutually exclusive. Furthermore any curve-specific \f(CW\*(C`\-\-style\*(C'\fR
|
|
overrides the global \f(CW\*(C`\-\-styleall\*(C'\fR or \f(CW\*(C`\-\-with\*(C'\fR setting.
|
|
.SS "Data formats"
|
|
.IX Subsection "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
|
|
.PP
|
|
\fIDomain selection\fR
|
|
.IX Subsection "Domain selection"
|
|
.PP
|
|
If \f(CW\*(C`\-\-domain\*(C'\fR is passed in, the first value on each line of input is
|
|
interpreted as the \fIX\fR\-value for the rest of the data on that line. Without
|
|
\&\f(CW\*(C`\-\-domain\*(C'\fR the \fIX\fR\-value is the line number, and the first value on a line is
|
|
a plain data point like the others. Default is \f(CW\*(C`\-\-nodomain\*(C'\fR. Thus the original
|
|
example above produces 2 curves, with \fB1,2,3,4,5\fR as the \fIX\fR\-values. If we run
|
|
the same command with \f(CW\*(C`\-\-domain\*(C'\fR:
|
|
.PP
|
|
.Vb 1
|
|
\& $ seq 5 | awk \*(Aq{print 2*$1, $1*$1}\*(Aq | feedgnuplot \-\-domain
|
|
.Ve
|
|
.PP
|
|
we get only 1 curve, with \fB2,4,6,8,10\fR as the \fIX\fR\-values. As many points as
|
|
desired can appear on a single line, but all points on a line are associated
|
|
with the \fIX\fR\-value at the start of that line.
|
|
.PP
|
|
\fICurve indexing\fR
|
|
.IX Subsection "Curve indexing"
|
|
.PP
|
|
We index the curves in one of 3 ways: sequentially, explicitly with a
|
|
\&\f(CW\*(C`\-\-dataid\*(C'\fR or by \f(CW\*(C`\-\-vnlog\*(C'\fR headers.
|
|
.PP
|
|
By default, each column represents a separate curve. The first column (after any
|
|
domain) is curve \f(CW0\fR. The next one is curve \f(CW1\fR and so on. This is fine unless
|
|
sparse data is to be plotted. With the \f(CW\*(C`\-\-dataid\*(C'\fR option, each point is
|
|
represented by 2 values: a string identifying the curve, and the value itself.
|
|
If we add \f(CW\*(C`\-\-dataid\*(C'\fR to the original example:
|
|
.PP
|
|
.Vb 1
|
|
\& $ seq 5 | awk \*(Aq{print 2*$1, $1*$1}\*(Aq | feedgnuplot \-\-dataid \-\-autolegend
|
|
.Ve
|
|
.PP
|
|
we get 5 different curves with one point in each. The first column, as produced
|
|
by \f(CW\*(C`awk\*(C'\fR, is \fB2,4,6,8,10\fR. These are interpreted as the IDs of the curves to
|
|
be plotted.
|
|
.PP
|
|
If we're plotting \f(CW\*(C`vnlog\*(C'\fR data (<https://www.github.com/dkogan/vnlog>) then we
|
|
can get the curve IDs from the vnlog header. Vnlog is a trivial data format
|
|
where lines starting with \f(CW\*(C`#\*(C'\fR are comments and the first comment contains
|
|
column labels. If we have such data, \f(CW\*(C`feedgnuplot \-\-vnlog\*(C'\fR can interpret these
|
|
column labels if the \f(CW\*(C`vnlog\*(C'\fR perl modules are available.
|
|
.PP
|
|
The \f(CW\*(C`\-\-autolegend\*(C'\fR 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. \f(CW\*(C`\-\-domain\*(C'\fR can be used in
|
|
conjunction with \f(CW\*(C`\-\-dataid\*(C'\fR or \f(CW\*(C`\-\-vnlog\*(C'\fR.
|
|
.PP
|
|
\fIMulti-value style support\fR
|
|
.IX Subsection "Multi-value style support"
|
|
.PP
|
|
Depending on how gnuplot is plotting the data, more than one value may be needed
|
|
to represent the range of a single point. Basic 2D plots have 2 numbers
|
|
representing each point: 1 domain and 1 range. But if plotting with
|
|
\&\f(CW\*(C`\-\-circles\*(C'\fR, for instance, then there's an extra range value: the radius. Many
|
|
other gnuplot styles require more data: errorbars, variable colors (\f(CW\*(C`with
|
|
points palette\*(C'\fR), variable sizes (\f(CW\*(C`with points ps variable\*(C'\fR), labels and so on.
|
|
The feedgnuplot tool itself does not know about all these intricacies, but they
|
|
can still be used, by specifying the specific style with \f(CW\*(C`\-\-style\*(C'\fR, and
|
|
specifying how many values are needed for each point with any of
|
|
\&\f(CW\*(C`\-\-rangesizeall\*(C'\fR, \f(CW\*(C`\-\-tuplesizeall\*(C'\fR, \f(CW\*(C`\-\-rangesize\*(C'\fR, \f(CW\*(C`\-\-tuplesize\*(C'\fR. These
|
|
options are required \fIonly\fR for styles not explicitly supported by feedgnuplot;
|
|
supported styles do the right thing automatically.
|
|
.PP
|
|
Specific example: if making a 2d plot of y error bars, the exact format can be
|
|
queried by running \f(CW\*(C`gnuplot\*(C'\fR and invoking \f(CW\*(C`help yerrorbars\*(C'\fR. This tells us
|
|
that there's a 3\-column form: \f(CW\*(C`x y ydelta\*(C'\fR and a 4\-column form: \f(CW\*(C`x y ylow
|
|
yhigh\*(C'\fR. With 2d plots feedgnuplot will always output the 1\-value domain \f(CW\*(C`x\*(C'\fR, so
|
|
the rangesize is 2 and 3 respectively. Thus the following are equivalent:
|
|
.PP
|
|
.Vb 3
|
|
\& $ echo \*(Aq1 2 0.3
|
|
\& 2 3 0.4
|
|
\& 3 4 0.5\*(Aq | feedgnuplot \-\-domain \-\-rangesizeall 2 \-\-with \*(Aqyerrorbars\*(Aq
|
|
\&
|
|
\& $ echo \*(Aq1 2 0.3
|
|
\& 2 3 0.4
|
|
\& 3 4 0.5\*(Aq | feedgnuplot \-\-domain \-\-tuplesizeall 3 \-\-with \*(Aqyerrorbars\*(Aq
|
|
\&
|
|
\& $ echo \*(Aq1 2 1.7 2.3
|
|
\& 2 3 2.6 3.4
|
|
\& 3 4 3.5 4.5\*(Aq | feedgnuplot \-\-domain \-\-rangesizeall 3 \-\-with \*(Aqyerrorbars\*(Aq
|
|
.Ve
|
|
.PP
|
|
\fI3D data\fR
|
|
.IX Subsection "3D data"
|
|
.PP
|
|
To plot 3D data, pass in \f(CW\*(C`\-\-3d\*(C'\fR. \f(CW\*(C`\-\-domain\*(C'\fR \s-1MUST\s0 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 (\fIZ\fR as a function of \fIX\fR and \fIY\fR
|
|
instead of \fIY\fR as a function of \fIX\fR). 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.
|
|
.PP
|
|
\fITime/date data\fR
|
|
.IX Subsection "Time/date data"
|
|
.PP
|
|
If the input data domain is a time/date, this can be interpreted with
|
|
\&\f(CW\*(C`\-\-timefmt\*(C'\fR. This option takes a single argument: the format to use to parse
|
|
the data. The format is documented in 'set timefmt' in gnuplot, although the
|
|
common flags that \f(CW\*(C`strftime\*(C'\fR understands are generally supported. The backslash
|
|
sequences in the format are \fInot\fR supported, so if you want a tab, put in a tab
|
|
instead of \et. Whitespace in the format \fIis\fR supported. When this flag is
|
|
given, some other options act a little bit differently:
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-xlen\*(C'\fR is an \fIinteger\fR in seconds
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-xmin\*(C'\fR and \f(CW\*(C`\-\-xmax\*(C'\fR \fImust\fR use the format passed in to \f(CW\*(C`\-\-timefmt\*(C'\fR
|
|
.PP
|
|
Using this option changes both the way the input is parsed \fIand\fR the way the
|
|
x\-axis tics are labelled. Gnuplot tries to be intelligent in this labelling, but
|
|
it doesn't always do what the user wants. The labelling can be controlled with
|
|
the gnuplot \f(CW\*(C`set format\*(C'\fR command, which takes the same type of format string as
|
|
\&\f(CW\*(C`\-\-timefmt\*(C'\fR. Example:
|
|
.PP
|
|
.Vb 5
|
|
\& $ sar 1 \-1 |
|
|
\& awk \*(Aq$1 ~ /..:..:../ && $8 ~/^[0\-9\e.]*$/ {print $1,$8; fflush()}\*(Aq |
|
|
\& feedgnuplot \-\-stream \-\-domain
|
|
\& \-\-lines \-\-timefmt \*(Aq%H:%M:%S\*(Aq
|
|
\& \-\-set \*(Aqformat x "%H:%M:%S"\*(Aq
|
|
.Ve
|
|
.PP
|
|
This plots the 'idle' \s-1CPU\s0 consumption against time.
|
|
.PP
|
|
Note that while gnuplot supports the time/date on any axis, \fIfeedgnuplot\fR
|
|
currently supports it \fIonly\fR as the x\-axis domain. This may change in the
|
|
future.
|
|
.SS "Real-time streaming data"
|
|
.IX Subsection "Real-time streaming data"
|
|
To plot real-time data, pass in the \f(CW\*(C`\-\-stream [refreshperiod]\*(C'\fR option. Data
|
|
will then be plotted as it is received. The plot will be updated every
|
|
\&\f(CW\*(C`refreshperiod\*(C'\fR 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 \fIonly\fR 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. Look in
|
|
\&\*(L"Special data commands\*(R" for more information.
|
|
.PP
|
|
To plot only the most recent data (instead of \fIall\fR the data), \f(CW\*(C`\-\-xlen
|
|
windowsize\*(C'\fR can be given. This will create an constantly-updating, scrolling
|
|
view of the recent past. \f(CW\*(C`windowsize\*(C'\fR should be replaced by the desired length
|
|
of the domain window to plot, in domain units (passed-in values if \f(CW\*(C`\-\-domain\*(C'\fR
|
|
or line numbers otherwise). If the domain is a time/date via \f(CW\*(C`\-\-timefmt\*(C'\fR, then
|
|
\&\f(CW\*(C`windowsize\*(C'\fR is and \fIinteger\fR in seconds. If we're plotting a histogram, then
|
|
\&\f(CW\*(C`\-\-xlen\*(C'\fR causes a histogram over a moving window to be computed. The subtlely
|
|
here is that with a histogram you don't actually \fIsee\fR the domain since only
|
|
the range is analyzed. But the domain is still there, and can be utilized with
|
|
\&\f(CW\*(C`\-\-xlen\*(C'\fR. With \f(CW\*(C`\-\-xlen\*(C'\fR we can plot \fIonly\fR histograms or \fIonly\fR
|
|
\&\fInon\fR\-histograms.
|
|
.PP
|
|
\fISpecial data commands\fR
|
|
.IX Subsection "Special data commands"
|
|
.PP
|
|
If we are reading streaming data, the input stream can contain special commands
|
|
in addition to the raw data. Feedgnuplot looks for these at the start of every
|
|
input line. If a command is detected, the rest of the line is discarded. These
|
|
commands are
|
|
.ie n .IP """replot""" 4
|
|
.el .IP "\f(CWreplot\fR" 4
|
|
.IX Item "replot"
|
|
This command refreshes the plot right now, instead of waiting for the next
|
|
refresh time indicated by the timer. This command works in addition to the timed
|
|
refresh, as indicated by \f(CW\*(C`\-\-stream [refreshperiod]\*(C'\fR.
|
|
.ie n .IP """clear""" 4
|
|
.el .IP "\f(CWclear\fR" 4
|
|
.IX Item "clear"
|
|
This command clears out the current data in the plot. The plotting process
|
|
continues, however, to any data following the \f(CW\*(C`clear\*(C'\fR.
|
|
.ie n .IP """exit""" 4
|
|
.el .IP "\f(CWexit\fR" 4
|
|
.IX Item "exit"
|
|
This command causes feedgnuplot to exit.
|
|
.SS "Hardcopy output"
|
|
.IX Subsection "Hardcopy output"
|
|
The script is able to produce hardcopy output with \f(CW\*(C`\-\-hardcopy outputfile\*(C'\fR. The
|
|
output type can be inferred from the filename, if \fB.ps\fR, \fB.eps\fR, \fB.pdf\fR,
|
|
\&\fB.svg\fR, \fB.png\fR or \fB.gp\fR is requested. If any other file type is requested,
|
|
\&\f(CW\*(C`\-\-terminal\*(C'\fR \fImust\fR be passed in to tell gnuplot how to make the plot. If
|
|
\&\f(CW\*(C`\-\-terminal\*(C'\fR is passed in, then the \f(CW\*(C`\-\-hardcopy\*(C'\fR argument only provides the
|
|
output filename.
|
|
.PP
|
|
The \fB.gp\fR output is special. Instead of asking gnuplot to plot to a particular
|
|
terminal, writing to a \fB.gp\fR simply dumps a self-executable gnuplot script into
|
|
the given file. This is similar to what \f(CW\*(C`\-\-dump\*(C'\fR does, but writes to a file,
|
|
and makes sure that the file can be self-executing.
|
|
.SS "Self-plotting data files"
|
|
.IX Subsection "Self-plotting data files"
|
|
This script can be used to enable self-plotting data files. There are several
|
|
ways of doing this: with a shebang (#!) or with inline perl data.
|
|
.PP
|
|
\fISelf-plotting data with a #!\fR
|
|
.IX Subsection "Self-plotting data with a #!"
|
|
.PP
|
|
A self-plotting, executable data file \f(CW\*(C`data\*(C'\fR is formatted as
|
|
.PP
|
|
.Vb 10
|
|
\& $ 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
|
|
.Ve
|
|
.PP
|
|
This is the shebang (#!) line followed by the data, formatted as before. The
|
|
data file can be plotted simply with
|
|
.PP
|
|
.Vb 1
|
|
\& $ ./data
|
|
.Ve
|
|
.PP
|
|
The caveats here are that on Linux the whole #! line is limited to 127
|
|
characters 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.
|
|
.PP
|
|
\fISelf-plotting data with gnuplot\fR
|
|
.IX Subsection "Self-plotting data with gnuplot"
|
|
.PP
|
|
Running \f(CW\*(C`feedgnuplot \-\-hardcopy plotdata.gp ....\*(C'\fR will create a self-executable
|
|
gnuplot script in \f(CW\*(C`plotdata.gp\*(C'\fR
|
|
.PP
|
|
\fISelf-plotting data with perl inline data\fR
|
|
.IX Subsection "Self-plotting data with perl inline data"
|
|
.PP
|
|
Perl supports storing data and code in the same file. This can also be used to
|
|
create self-plotting files:
|
|
.PP
|
|
.Vb 4
|
|
\& $ cat plotdata.pl
|
|
\& #!/usr/bin/perl
|
|
\& use strict;
|
|
\& use warnings;
|
|
\&
|
|
\& open PLOT, "| feedgnuplot \-\-lines \-\-points" or die "Couldn\*(Aqt open plotting pipe";
|
|
\& while( <DATA> )
|
|
\& {
|
|
\& my @xy = split;
|
|
\& print PLOT "@xy\en";
|
|
\& }
|
|
\& _\|_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
|
|
.Ve
|
|
.PP
|
|
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.
|
|
.SH "ARGUMENTS"
|
|
.IX Header "ARGUMENTS"
|
|
.IP "\(bu" 4
|
|
\&\-\-\f(CW\*(C`[no]domain\*(C'\fR
|
|
.Sp
|
|
If enabled, the first element of each line is the domain variable. If not, the
|
|
point index is used
|
|
.IP "\(bu" 4
|
|
\&\-\-\f(CW\*(C`[no]dataid\*(C'\fR
|
|
.Sp
|
|
If enabled, each data point is preceded by the \s-1ID\s0 of the data set that point
|
|
corresponds to. This \s-1ID\s0 is interpreted as a string, \s-1NOT\s0 as just a number. If not
|
|
enabled, the order of the point is used.
|
|
.Sp
|
|
As an example, if line 3 of the input is \*(L"0 9 1 20\*(R" then
|
|
.RS 4
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-nodomain \-\-nodataid\*(C'\fR would parse the 4 numbers as points in 4 different
|
|
curves at x=3
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-domain \-\-nodataid\*(C'\fR 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
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-nodomain \-\-dataid\*(C'\fR 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
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-domain \-\-dataid\*(C'\fR would parse the 4 numbers as a single point at
|
|
x=0. Here 9 is the data \s-1ID\s0 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 \s-1ID 20\s0
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-vnlog\*(C'\fR
|
|
.Sp
|
|
Vnlog is a trivial data format where lines starting with \f(CW\*(C`#\*(C'\fR are comments and
|
|
the first comment contains column labels. Some tools for working with such data
|
|
are available from the \f(CW\*(C`vnlog\*(C'\fR project: <https://www.github.com/dkogan/vnlog>.
|
|
With the \f(CW\*(C`vnlog\*(C'\fR perl modules installed, we can read the vnlog column headers
|
|
with \f(CW\*(C`feedgnuplot \-\-vnlog\*(C'\fR. This replaces \f(CW\*(C`\-\-dataid\*(C'\fR, and we can do all the
|
|
normal things with these headers. For instance \f(CW\*(C`feedgnuplot \-\-vnlog
|
|
\&\-\-autolegend\*(C'\fR will generate plot legends for each column in the vnlog, using the
|
|
vnlog column label in the legend.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-[no]3d\*(C'\fR
|
|
.Sp
|
|
Do [not] plot in 3D. This only makes sense with \f(CW\*(C`\-\-domain\*(C'\fR. Each domain here is
|
|
an (x,y) tuple
|
|
.IP "\(bu" 4
|
|
\&\-\-\f(CW\*(C`timefmt [format]\*(C'\fR
|
|
.Sp
|
|
Interpret the X data as a time/date, parsed with the given format
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-colormap\*(C'\fR
|
|
.Sp
|
|
Show a colormapped xy plot. Requires extra data for the color. zmin/zmax can be
|
|
used to set the extents of the colors. Automatically sets the
|
|
\&\f(CW\*(C`\-\-rangesize\*(C'\fR/\f(CW\*(C`\-\-tuplesize\*(C'\fR.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-stream [period]\*(C'\fR
|
|
.Sp
|
|
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 \fIonly\fR when the incoming data dictates this. See the
|
|
\&\*(L"Real-time streaming data\*(R" section of the man page.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-[no]lines\*(C'\fR
|
|
.Sp
|
|
Do [not] draw lines to connect consecutive points
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-[no]points\*(C'\fR
|
|
.Sp
|
|
Do [not] draw points
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-circles\*(C'\fR
|
|
.Sp
|
|
Plot with circles. This requires a radius be specified for each point.
|
|
Automatically sets the \f(CW\*(C`\-\-rangesize\*(C'\fR/\f(CW\*(C`\-\-tuplesize\*(C'\fR. \f(CW\*(C`Not\*(C'\fR supported for 3d
|
|
plots.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-title xxx\*(C'\fR
|
|
.Sp
|
|
Set the title of the plot
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-legend curveID legend\*(C'\fR
|
|
.Sp
|
|
Set the label for a curve plot. Use this option multiple times for multiple
|
|
curves. With \f(CW\*(C`\-\-dataid\*(C'\fR, curveID is the \s-1ID.\s0 Otherwise, it's the index of the
|
|
curve, starting at 0
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-autolegend\*(C'\fR
|
|
.Sp
|
|
Use the curve IDs for the legend. Titles given with \f(CW\*(C`\-\-legend\*(C'\fR override these
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-xlen xxx\*(C'\fR
|
|
.Sp
|
|
When using \f(CW\*(C`\-\-stream\*(C'\fR, sets the size of the x\-window to plot. Omit this or set
|
|
it to 0 to plot \s-1ALL\s0 the data. Does not make sense with 3d plots. Implies
|
|
\&\f(CW\*(C`\-\-monotonic\*(C'\fR. If we're plotting a histogram, then \f(CW\*(C`\-\-xlen\*(C'\fR causes a histogram
|
|
over a moving window to be computed. The subtlely here is that with a histogram
|
|
you don't actually \fIsee\fR the domain since only the range is analyzed. But the
|
|
domain is still there, and can be utilized with \f(CW\*(C`\-\-xlen\*(C'\fR. With \f(CW\*(C`\-\-xlen\*(C'\fR we can
|
|
plot \fIonly\fR histograms or \fIonly\fR \fInon\fR\-histograms.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-xmin/xmax/ymin/ymax/y2min/y2max/zmin/zmax xxx\*(C'\fR
|
|
.Sp
|
|
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
|
|
\&\fIonly\fR to 3d plots or colormaps. Note that there is no \f(CW\*(C`\-\-xrange\*(C'\fR to set both
|
|
sides at once or \f(CW\*(C`\-\-xinv\*(C'\fR to flip the axis around: anything more than the
|
|
basics supported in this option is clearly obtainable by talking to gnuplot, for
|
|
instance \f(CW\*(C`\-\-set \*(Aqxrange [20:10]\*(Aq\*(C'\fR to set the given inverted bounds.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-xlabel/ylabel/y2label/zlabel xxx\*(C'\fR
|
|
.Sp
|
|
Label the given axis. The y2\-axis label does not apply to 3d plots while the
|
|
z\-axis label applies \fIonly\fR to 3d plots.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-y2 xxx\*(C'\fR
|
|
.Sp
|
|
Plot the data specified by this curve \s-1ID\s0 on the y2 axis. Without \f(CW\*(C`\-\-dataid\*(C'\fR,
|
|
the \s-1ID\s0 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
|
|
.Sp
|
|
.Vb 1
|
|
\& \-\-y2 curveid \-\-style curveid \*(Aqlinewidth 3\*(Aq
|
|
.Ve
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-histogram curveID\*(C'\fR
|
|
.Sp
|
|
Set up a this specific curve to plot a histogram. The bin width is given with
|
|
the \f(CW\*(C`\-\-binwidth\*(C'\fR option (assumed 1.0 if omitted). If a drawing style is not
|
|
specified for this curve (\f(CW\*(C`\-\-curvestyle\*(C'\fR) or all curves (\f(CW\*(C`\-\-with\*(C'\fR,
|
|
\&\f(CW\*(C`\-\-curvestyleall\*(C'\fR) then the default histogram style is set: filled boxes with
|
|
borders. This is what the user generally wants. This works with \f(CW\*(C`\-\-domain\*(C'\fR
|
|
and/or \f(CW\*(C`\-\-stream\*(C'\fR, but in those cases the x\-value is used \fIonly\fR to cull old
|
|
data because of \f(CW\*(C`\-\-xlen\*(C'\fR or \f(CW\*(C`\-\-monotonic\*(C'\fR. I.e. the domain values are \fInot\fR
|
|
drawn in any way. Can be passed multiple times, or passed a comma\- separated
|
|
list
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-binwidth width\*(C'\fR
|
|
.Sp
|
|
The width of bins when making histograms. This setting applies to \s-1ALL\s0 histograms
|
|
in the plot. Defaults to 1.0 if not given.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-histstyle style\*(C'\fR
|
|
.Sp
|
|
Normally, histograms are generated with the 'smooth frequency' gnuplot style.
|
|
\&\f(CW\*(C`\-\-histstyle\*(C'\fR can be used to select different \f(CW\*(C`smooth\*(C'\fR settings (see the
|
|
gnuplot \f(CW\*(C`help smooth\*(C'\fR page for more info). Allowed values are 'frequency' (the
|
|
default), 'fnormal' (available in very recent gnuplots), 'unique', 'cumulative'
|
|
and 'cnormal'. 'fnormal' is a normalized histogram. '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 'frequency' histogram.
|
|
\&'cnormal' is like 'cumulative', but rescaled to end up at 1.0.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-style curveID style\*(C'\fR
|
|
.Sp
|
|
Additional styles per curve. With \f(CW\*(C`\-\-dataid\*(C'\fR, curveID is the \s-1ID.\s0 Otherwise,
|
|
it's the index of the curve, starting at 0. curveID can be a comma-separated
|
|
list of IDs to which the given style should apply. Use this option multiple
|
|
times for multiple curves. \f(CW\*(C`\-\-styleall\*(C'\fR does \fInot\fR apply to curves that have a
|
|
\&\f(CW\*(C`\-\-style\*(C'\fR.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-curvestyle curveID\*(C'\fR
|
|
.Sp
|
|
Synonym for \f(CW\*(C`\-\-style\*(C'\fR
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-styleall xxx\*(C'\fR
|
|
.Sp
|
|
Additional styles for all curves that have no \f(CW\*(C`\-\-style\*(C'\fR. This is overridden by
|
|
any applicable \f(CW\*(C`\-\-style\*(C'\fR. Exclusive with \f(CW\*(C`\-\-with\*(C'\fR.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-curvestyleall xxx\*(C'\fR
|
|
.Sp
|
|
Synonym for \f(CW\*(C`\-\-styleall\*(C'\fR
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-with xxx\*(C'\fR
|
|
.Sp
|
|
Same as \f(CW\*(C`\-\-styleall\*(C'\fR, but prefixed with \*(L"with\*(R". Thus
|
|
.Sp
|
|
.Vb 1
|
|
\& \-\-with boxes
|
|
.Ve
|
|
.Sp
|
|
is equivalent to
|
|
.Sp
|
|
.Vb 1
|
|
\& \-\-styleall \*(Aqwith boxes\*(Aq
|
|
.Ve
|
|
.Sp
|
|
Exclusive with \f(CW\*(C`\-\-styleall\*(C'\fR.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-extracmds xxx\*(C'\fR
|
|
.Sp
|
|
Additional commands to pass on to gnuplot verbatim. These could contain extra
|
|
global styles for instance. Can be passed multiple times.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-set xxx\*(C'\fR
|
|
.Sp
|
|
Additional 'set' commands to pass on to gnuplot verbatim. \f(CW\*(C`\-\-set \*(Aqa b c\*(Aq\*(C'\fR will
|
|
result in gnuplot seeing a \f(CW\*(C`set a b c\*(C'\fR command. Can be passed multiple times.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-unset xxx\*(C'\fR
|
|
.Sp
|
|
Additional 'unset' commands to pass on to gnuplot verbatim. \f(CW\*(C`\-\-unset \*(Aqa b c\*(Aq\*(C'\fR
|
|
will result in gnuplot seeing a \f(CW\*(C`unset a b c\*(C'\fR command. Can be passed multiple
|
|
times.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-image filename\*(C'\fR
|
|
.Sp
|
|
Overlays the data on top of a raster image given in \f(CW\*(C`filename\*(C'\fR. This is passed
|
|
through to gnuplot via \f(CW\*(C`\-\-equation\*(C'\fR, and is not interpreted by \f(CW\*(C`feedgnuplot\*(C'\fR
|
|
other than checking for existence. Usually images have their origin at the
|
|
top-left corner, while plots have it in the bottom-left corner instead. Thus if
|
|
the y\-axis extents are not specified (\f(CW\*(C`\-\-ymin\*(C'\fR, \f(CW\*(C`\-\-ymax\*(C'\fR, \f(CW\*(C`\-\-set \*(Aqyrange
|
|
\&...\*(Aq\*(C'\fR) this option will also flip around the y axis to make the image appear
|
|
properly. Since this option is just a passthrough to gnuplot, finer control can
|
|
be achieved by passing in \f(CW\*(C`\-\-equation\*(C'\fR and \f(CW\*(C`\-\-set yrange ...\*(C'\fR directly.
|
|
.Sp
|
|
\&\f(CW\*(C`\-\-equation xxx\*(C'\fR
|
|
.Sp
|
|
Gnuplot can plot both data and symbolic equations. \f(CW\*(C`feedgnuplot\*(C'\fR generally
|
|
plots data, but with this option can plot symbolic equations \fIalso\fR. This is
|
|
generally intended to augment data plots, since for equation-only plots you
|
|
don't need \f(CW\*(C`feedgnuplot\*(C'\fR. \f(CW\*(C`\-\-equation\*(C'\fR can be passed multiple times for
|
|
multiple equations. The given strings are passed to gnuplot directly without
|
|
anything added or removed, so styling and such should be applied in the string.
|
|
A basic example:
|
|
.Sp
|
|
.Vb 3
|
|
\& seq 100 | awk \*(Aq{print $1/10, $1/100}\*(Aq |
|
|
\& feedgnuplot \-\-with \*(Aqlines lw 3\*(Aq \-\-domain \-\-ymax 1
|
|
\& \-\-equation \*(Aqsin(x)/x\*(Aq \-\-equation \*(Aqcos(x)/x with lines lw 4\*(Aq
|
|
.Ve
|
|
.Sp
|
|
Here I plot the incoming data (points along a line) with the given style (a line
|
|
with thickness 3), \fIand\fR I plot two damped sinusoids on the same plot. The
|
|
sinusoids are not affected by \f(CW\*(C`feedgnuplot\*(C'\fR styling, so their styles are set
|
|
separately, as in this example. More complicated example:
|
|
.Sp
|
|
.Vb 3
|
|
\& seq 360 | perl \-nE \*(Aq$th=$_/360 * 3.14*2; $c=cos($th); $s=sin($th); say "$c $s"\*(Aq |
|
|
\& feedgnuplot \-\-domain \-\-square
|
|
\& \-\-set parametric \-\-set "trange [0:2*3.14]" \-\-equation "sin(t),cos(t)"
|
|
.Ve
|
|
.Sp
|
|
Here the data I generate is points along the unit circle. I plot these as
|
|
points, and I \fIalso\fR plot a true circle as a parametric equation.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-square\*(C'\fR
|
|
.Sp
|
|
Plot data with aspect ratio 1. For 3D plots, this controls the aspect ratio for
|
|
all 3 axes
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-square_xy\*(C'\fR
|
|
.Sp
|
|
For 3D plots, set square aspect ratio for \s-1ONLY\s0 the x,y axes
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-hardcopy xxx\*(C'\fR
|
|
.Sp
|
|
If not streaming, output to a file specified here. Format inferred from
|
|
filename, unless specified by \f(CW\*(C`\-\-terminal\*(C'\fR. If \f(CW\*(C`\-\-terminal\*(C'\fR is given,
|
|
\&\f(CW\*(C`\-\-hardcopy\*(C'\fR sets \fIonly\fR the output filename.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-terminal xxx\*(C'\fR
|
|
.Sp
|
|
String passed to 'set terminal'. No attempts are made to validate this.
|
|
\&\f(CW\*(C`\-\-hardcopy\*(C'\fR sets this to some sensible defaults if \f(CW\*(C`\-\-hardcopy\*(C'\fR is set to a
|
|
filename ending in \f(CW\*(C`.png\*(C'\fR, \f(CW\*(C`.pdf\*(C'\fR, \f(CW\*(C`.ps\*(C'\fR, \f(CW\*(C`.eps\*(C'\fR or \f(CW\*(C`.svg\*(C'\fR. If any other
|
|
file type is desired, use both \f(CW\*(C`\-\-hardcopy\*(C'\fR and \f(CW\*(C`\-\-terminal\*(C'\fR
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-maxcurves N\*(C'\fR
|
|
.Sp
|
|
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
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-monotonic\*(C'\fR
|
|
.Sp
|
|
If \f(CW\*(C`\-\-domain\*(C'\fR 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 \f(CW\*(C`\-\-monotonic\*(C'\fR, all data is
|
|
kept. Does not make sense with 3d plots. No \f(CW\*(C`\-\-monotonic\*(C'\fR by default. The data
|
|
is replotted before being purged. This is useful in streaming plots where the
|
|
incoming data represents multiple iterations of the same process (repeated
|
|
simulations of the same period in time, for instance).
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-rangesize curveID N\*(C'\fR
|
|
.Sp
|
|
The options \f(CW\*(C`\-\-rangesizeall\*(C'\fR and \f(CW\*(C`\-\-rangesize\*(C'\fR set the number of values are
|
|
needed to represent each point being plotted (see \*(L"Multi-value style
|
|
support\*(R" above). These options are \fIonly\fR needed if unknown styles are used,
|
|
with \f(CW\*(C`\-\-styleall\*(C'\fR or \f(CW\*(C`\-\-with\*(C'\fR for instance.
|
|
.Sp
|
|
\&\f(CW\*(C`\-\-rangesize\*(C'\fR is used to set how many values are needed to represent the range
|
|
of a point for a particular curve. This overrides any defaults that may exist
|
|
for this curve only.
|
|
.Sp
|
|
With \f(CW\*(C`\-\-dataid\*(C'\fR, curveID is the \s-1ID.\s0 Otherwise, it's the index of the curve,
|
|
starting at 0. curveID can be a comma-separated list of IDs to which the given
|
|
rangesize should apply.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-tuplesize curveID N\*(C'\fR
|
|
.Sp
|
|
Very similar to \f(CW\*(C`\-\-rangesize\*(C'\fR, but instead of specifying the \fIrange\fR only,
|
|
this specifies the whole tuple. For instance if we're plotting circles, the
|
|
tuplesize is 3: \f(CW\*(C`x,y,radius\*(C'\fR. In a 2D plot there's a 1\-dimensional domain:
|
|
\&\f(CW\*(C`x\*(C'\fR, so the rangesize is 2: \f(CW\*(C`y,radius\*(C'\fR. This dimensionality can be given
|
|
either way.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-rangesizeall N\*(C'\fR
|
|
.Sp
|
|
Like \f(CW\*(C`\-\-rangesize\*(C'\fR, but applies to \fIall\fR the curves.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-tuplesizeall N\*(C'\fR
|
|
.Sp
|
|
Like \f(CW\*(C`\-\-tuplesize\*(C'\fR, but applies to \fIall\fR the curves.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-dump\*(C'\fR
|
|
.Sp
|
|
Instead of printing to gnuplot, print to \s-1STDOUT.\s0 Very useful for debugging. It
|
|
is possible to send the output produced this way to gnuplot directly.
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-exit\*(C'\fR
|
|
.Sp
|
|
This controls what happens when the input data is exhausted, or when some part
|
|
of the \f(CW\*(C`feedgnuplot\*(C'\fR pipeline is killed. This option does different things
|
|
depending on whether \f(CW\*(C`\-\-stream\*(C'\fR is active, so read this closely.
|
|
.Sp
|
|
With interactive gnuplot terminals (qt, x11, wxt), the plot windows live in a
|
|
separate process from the main \f(CW\*(C`gnuplot\*(C'\fR process. It is thus possible for the
|
|
main \f(CW\*(C`gnuplot\*(C'\fR process to exit, while leaving the plot windows up (a caveat is
|
|
that such decapitated windows aren't interactive). There are 3 possible states
|
|
of the polotting pipeline:
|
|
.RS 4
|
|
.ie n .IP "Alive: ""feedgnuplot"", ""gnuplot"" alive, plot window process alive, no shell prompt (shell busy with ""feedgnuplot"")" 4
|
|
.el .IP "Alive: \f(CWfeedgnuplot\fR, \f(CWgnuplot\fR alive, plot window process alive, no shell prompt (shell busy with \f(CWfeedgnuplot\fR)" 4
|
|
.IX Item "Alive: feedgnuplot, gnuplot alive, plot window process alive, no shell prompt (shell busy with feedgnuplot)"
|
|
.PD 0
|
|
.ie n .IP "Half-alive: ""feedgnuplot"", ""gnuplot"" dead, plot window process alive (but non-interactive), shell prompt available" 4
|
|
.el .IP "Half-alive: \f(CWfeedgnuplot\fR, \f(CWgnuplot\fR dead, plot window process alive (but non-interactive), shell prompt available" 4
|
|
.IX Item "Half-alive: feedgnuplot, gnuplot dead, plot window process alive (but non-interactive), shell prompt available"
|
|
.ie n .IP "Dead: ""feedgnuplot"", ""gnuplot"" dead, plot window process dead, shell prompt available" 4
|
|
.el .IP "Dead: \f(CWfeedgnuplot\fR, \f(CWgnuplot\fR dead, plot window process dead, shell prompt available" 4
|
|
.IX Item "Dead: feedgnuplot, gnuplot dead, plot window process dead, shell prompt available"
|
|
.RE
|
|
.RS 4
|
|
.PD
|
|
.Sp
|
|
The possibilities are:
|
|
.ie n .IP "No ""\-\-stream"", all data read in" 4
|
|
.el .IP "No \f(CW\-\-stream\fR, all data read in" 4
|
|
.IX Item "No --stream, all data read in"
|
|
.RS 4
|
|
.PD 0
|
|
.ie n .IP "no ""\-\-exit"" (default)" 4
|
|
.el .IP "no \f(CW\-\-exit\fR (default)" 4
|
|
.IX Item "no --exit (default)"
|
|
.PD
|
|
Alive. Need to Ctrl-C to get back into the shell
|
|
.ie n .IP """\-\-exit""" 4
|
|
.el .IP "\f(CW\-\-exit\fR" 4
|
|
.IX Item "--exit"
|
|
Half-alive. Non-interactive prompt up, and the shell accepts new commands.
|
|
Without \f(CW\*(C`\-\-stream\*(C'\fR the goal is to show a plot, so a Dead state would not be
|
|
useful.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.ie n .IP """\-\-stream"", all data read in or the ""feedgnuplot"" process terminated" 4
|
|
.el .IP "\f(CW\-\-stream\fR, all data read in or the \f(CWfeedgnuplot\fR process terminated" 4
|
|
.IX Item "--stream, all data read in or the feedgnuplot process terminated"
|
|
.RS 4
|
|
.PD 0
|
|
.ie n .IP "no ""\-\-exit"" (default)" 4
|
|
.el .IP "no \f(CW\-\-exit\fR (default)" 4
|
|
.IX Item "no --exit (default)"
|
|
.PD
|
|
Alive. Need to Ctrl-C to get back into the shell. This means that when making
|
|
live plots, the first Ctrl-C kills the data feeding process, but leaves the
|
|
final plot up for inspection. A second Ctrl-C kills feedgnuplot as well.
|
|
.ie n .IP """\-\-exit""" 4
|
|
.el .IP "\f(CW\-\-exit\fR" 4
|
|
.IX Item "--exit"
|
|
Dead. No plot is shown, and the shell accepts new commands. With \f(CW\*(C`\-\-stream\*(C'\fR the
|
|
goal is to show a plot as the data comes in, which we have been doing. Now that
|
|
we're done, we can clean up everything.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.RE
|
|
.RS 4
|
|
.Sp
|
|
Note that one usually invokes \f(CW\*(C`feedgnuplot\*(C'\fR as a part of a shell pipeline:
|
|
.Sp
|
|
.Vb 1
|
|
\& $ write_data | feedgnuplot
|
|
.Ve
|
|
.Sp
|
|
If the user terminates this pipeline with ^C, then \fIall\fR the processes in the
|
|
pipeline receive \s-1SIGINT.\s0 This normally kills \f(CW\*(C`feedgnuplot\*(C'\fR and all its
|
|
\&\f(CW\*(C`gnuplot\*(C'\fR children, and we let this happen unless \f(CW\*(C`\-\-stream\*(C'\fR and no \f(CW\*(C`\-\-exit\*(C'\fR.
|
|
If \f(CW\*(C`\-\-stream\*(C'\fR and no \f(CW\*(C`\-\-exit\*(C'\fR, then we ignore the first ^C. The data feeder
|
|
dies, and we behave as if the input data was exhausted. A second ^C kills us
|
|
also.
|
|
.RE
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-geometry\*(C'\fR
|
|
.Sp
|
|
If using X11, specifies the size, position of the plot window
|
|
.IP "\(bu" 4
|
|
\&\f(CW\*(C`\-\-version\*(C'\fR
|
|
.Sp
|
|
Print the version and exit
|
|
.SH "RECIPES"
|
|
.IX Header "RECIPES"
|
|
.SS "Basic plotting of piped data"
|
|
.IX Subsection "Basic plotting of piped data"
|
|
.Vb 6
|
|
\& $ seq 5 | awk \*(Aq{print 2*$1, $1*$1}\*(Aq
|
|
\& 2 1
|
|
\& 4 4
|
|
\& 6 9
|
|
\& 8 16
|
|
\& 10 25
|
|
\&
|
|
\& $ seq 5 | awk \*(Aq{print 2*$1, $1*$1}\*(Aq |
|
|
\& feedgnuplot \-\-lines \-\-points \-\-legend 0 "data 0" \-\-title "Test plot" \-\-y2 1
|
|
.Ve
|
|
.SS "Realtime plot of network throughput"
|
|
.IX Subsection "Realtime plot of network throughput"
|
|
Looks at wlan0 on Linux.
|
|
.PP
|
|
.Vb 3
|
|
\& $ while true; do sleep 1; cat /proc/net/dev; done |
|
|
\& gawk \*(Aq/wlan0/ {if(b) {print $2\-b; fflush()} b=$2}\*(Aq |
|
|
\& feedgnuplot \-\-lines \-\-stream \-\-xlen 10 \-\-ylabel \*(AqBytes/sec\*(Aq \-\-xlabel seconds
|
|
.Ve
|
|
.SS "Realtime plot of battery charge in respect to time"
|
|
.IX Subsection "Realtime plot of battery charge in respect to time"
|
|
Uses the result of the \f(CW\*(C`acpi\*(C'\fR command.
|
|
.PP
|
|
.Vb 3
|
|
\& $ while true; do acpi; sleep 15; done |
|
|
\& perl \-nE \*(AqBEGIN{ $| = 1; } /([0\-9]*)%/; say join(" ", time(), $1);\*(Aq |
|
|
\& feedgnuplot \-\-stream \-\-ymin 0 \-\-ymax 100 \-\-lines \-\-domain \-\-xlabel \*(AqTime\*(Aq \-\-timefmt \*(Aq%s\*(Aq \-\-ylabel "Battery charge (%)"
|
|
.Ve
|
|
.SS "Realtime plot of temperatures in an \s-1IBM\s0 Thinkpad"
|
|
.IX Subsection "Realtime plot of temperatures in an IBM Thinkpad"
|
|
Uses \f(CW\*(C`/proc/acpi/ibm/thermal\*(C'\fR, which reports temperatures at various locations
|
|
in a Thinkpad.
|
|
.PP
|
|
.Vb 2
|
|
\& $ while true; do cat /proc/acpi/ibm/thermal | awk \*(Aq{$1=""; print}\*(Aq ; sleep 1; done |
|
|
\& feedgnuplot \-\-stream \-\-xlen 100 \-\-lines \-\-autolegend \-\-ymax 100 \-\-ymin 20 \-\-ylabel \*(AqTemperature (deg C)\*(Aq
|
|
.Ve
|
|
.SS "Plotting a histogram of file sizes in a directory, granular to 10MB"
|
|
.IX Subsection "Plotting a histogram of file sizes in a directory, granular to 10MB"
|
|
.Vb 4
|
|
\& $ ls \-l | awk \*(Aq{print $5/1e6}\*(Aq |
|
|
\& feedgnuplot \-\-histogram 0
|
|
\& \-\-binwidth 10
|
|
\& \-\-ymin 0 \-\-xlabel \*(AqFile size (MB)\*(Aq \-\-ylabel Frequency
|
|
.Ve
|
|
.SS "Plotting a live histogram of the ping round-trip times for the past 20 seconds"
|
|
.IX Subsection "Plotting a live histogram of the ping round-trip times for the past 20 seconds"
|
|
.Vb 8
|
|
\& $ ping \-A \-D 8.8.8.8 |
|
|
\& perl \-anE \*(AqBEGIN { $| = 1; }
|
|
\& $F[0] =~ s/[\e[\e]]//g or next;
|
|
\& $F[7] =~ s/.*=//g or next;
|
|
\& say "$F[0] $F[7]"\*(Aq |
|
|
\& feedgnuplot \-\-stream \-\-domain \-\-histogram 0 \-\-binwidth 10 \e
|
|
\& \-\-xlabel \*(AqPing round\-trip time (s)\*(Aq \e
|
|
\& \-\-ylabel Frequency \-\-xlen 20
|
|
.Ve
|
|
.SS "Plotting points on top of an existing image"
|
|
.IX Subsection "Plotting points on top of an existing image"
|
|
This can be done with \f(CW\*(C`\-\-image\*(C'\fR:
|
|
.PP
|
|
.Vb 2
|
|
\& $ < features_xy.data
|
|
\& feedgnuplot \-\-points \-\-domain \-\-image "image.png"
|
|
.Ve
|
|
.PP
|
|
or with \f(CW\*(C`\-\-equation\*(C'\fR:
|
|
.PP
|
|
.Vb 4
|
|
\& $ < features_xy.data
|
|
\& feedgnuplot \-\-points \-\-domain
|
|
\& \-\-equation \*(Aq"image.png" binary filetype=auto flipy with rgbimage\*(Aq
|
|
\& \-\-set \*(Aqyrange [:] reverse\*(Aq
|
|
.Ve
|
|
.PP
|
|
The \f(CW\*(C`\-\-image\*(C'\fR invocation is a convenience wrapper for the \f(CW\*(C`\-\-equation\*(C'\fR
|
|
version. Finer control is available with \f(CW\*(C`\-\-equation\*(C'\fR.
|
|
.PP
|
|
Here an existing image is given to gnuplot verbatim, and data to plot on top of
|
|
it is interpreted by feedgnuplot as usual. \f(CW\*(C`flipy\*(C'\fR is useful here because
|
|
usually the y axis points up, but when looking at images, this is usually
|
|
reversed: the origin is the top-left pixel.
|
|
.SH "ACKNOWLEDGEMENT"
|
|
.IX Header "ACKNOWLEDGEMENT"
|
|
This program is originally based on the driveGnuPlots.pl script from
|
|
Thanassis Tsiodras. It is available from his site at
|
|
<http://users.softlab.ece.ntua.gr/~ttsiod/gnuplotStreaming.html>
|
|
.SH "REPOSITORY"
|
|
.IX Header "REPOSITORY"
|
|
<https://github.com/dkogan/feedgnuplot>
|
|
.SH "AUTHOR"
|
|
.IX Header "AUTHOR"
|
|
Dima Kogan, \f(CW\*(C`<dima@secretsauce.net>\*(C'\fR
|
|
.SH "LICENSE AND COPYRIGHT"
|
|
.IX Header "LICENSE AND COPYRIGHT"
|
|
Copyright 2011\-2012 Dima Kogan.
|
|
.PP
|
|
This program is free software; you can redistribute it and/or modify it
|
|
under the terms of either: the \s-1GNU\s0 General Public License as published
|
|
by the Free Software Foundation; or the Artistic License.
|
|
.PP
|
|
See http://dev.perl.org/licenses/ for more information.
|