Chart::Graph::Gnuplot
use Chart::Graph::Gnuplot qw(&gnuplot);
gnuplot(\%global_options, [\%data_set_options, \@matrix],
[\%data_set_options, \@x_column, \@y_column],
[\%data_set_options, < filename >], ... );
gnuplot() is a function in module Chart::Graph that lets you
generate graphs on the fly in perl. It was written as a front-end
application to gnuplot for hassle-free generation of
graphs. gnuplot() can be supplied with many of the same options and
arguments that can be given to gnuplot. For more information on
gnuplot see the end of this section.
gnuplot() has a very large number of options corresponding to
options available with the gnuplot application itself. This Perl
wrapper provides a large subset of the functionality of the
application.
+----------------------------------------------------------------------------+
| GLOBAL OPTIONS: |
+----------------+-----------------------------+-----------------------------+
| NAME | OPTIONS | DEFAULT |
+----------------+-----------------------------+-----------------------------+
|'title' | set your own title | 'untitled' |
|'output type' | 'pbm','gif','tgif','png', | 'png' |
| | 'svg' or "eps $epsoptions"| |
|'output file' | set your own output file, | 'untitled-gnuplot.png' |
| | undef to output to STDOUT | |
|'x-axis label' | set your own label | 'x-axis' |
|'y-axis label' | set your own label | 'y-axis' |
|'x2-axis label' | set your own label | none |
|'y2-axis label' | set your own label | none |
|'logscale x' | 0 or 1 | 0 |
|'logscale y' | 0 or 1 | 0 |
|'logscale x2' | 0 or 1 | 0 |
|'logscale y2' | 0 or 1 | 0 |
| 'xtics' | set your own tics on x-axis | none |
| | (see example below) | |
| 'x2tics' | set your own tics on x2-axis| none |
| | (see example below) | |
| 'ytics' | set your own tics on y-axis | none |
| | (see example below) | |
| 'y2tics' | set your own tics on y2-axis| none |
| | (see example below) | |
| 'xrange' | set xrange, accepts both | none |
| | string '[$xmin:$xmax]' | |
| | or arrayref [$xmin,$xmax] | |
| 'yrange' | set yrange, see xrange | none |
| | | |
| 'uts' | set your own range in unix | none |
| | timestamps, array ref: | |
| | [start_ts,end_ts,<scale>, | |
| | <use_local_tz> ] | |
| | see UNIX TIMESTAMPS example| |
| 'xdata' | 'time' to indicate that | none |
| | x-axis is date/time data | |
| 'ydata' | 'time' to indicate that | none |
| | y-axis is date/time data | |
| 'x2data' | 'time' to indicate that | none |
| | x2-axis is date/time data | |
| 'y2data' | 'time' to indicate that | none |
| | y2-axis is date/time data | |
| 'timefmt' | "Input date/time string" | none |
| | see Gnuplot manual for info| |
| 'format' | array ref: First element is | |
| | axis: 'x', 'y', 'x2', 'y2'.| |
| | Second element is | |
| | 'output date/time string" | |
| | see Gnuplot manual for info| |
| 'extra_opts' | set your own Gnuplot | none |
| | options, either an arrayref| |
| | or string ("\n"-separated) | |
| 'size' | scale the display size of | none |
| | the plot, arrayref [$x, $y]| |
+----------------+-----------------------------+-----------------------------+
+----------------------------------------------------------------------------+
| Data Set Options: |
+----------------+-----------------------------+-----------------------------+
| Name | Options | Default |
+----------------+-----------------------------+-----------------------------+
| 'type' | 'matrix', 'columns', 'file',| none |
| | 'function', see examples | |
| | below | |
| 'title' | set your own title | 'untitled data' |
| 'style' | 'points','lines','impulses' | 'points' |
| | 'errorbars', etc... | |
| | see ERRORBARS example | |
| 'axes' | 'x1y1', 'x2y2', 'x1y2', etc.| 'x1y1' |
| 'using' | map data to what will be | '1:2' |
| | plotted, see ERRORBARS | |
| | example | |
+----------------+-----------------------------+-----------------------------+
Data can be presented to Chart::Graph::Gnuplot in one of 3 formats for
the convenience of the user:
\@matrix: an array reference of [x,y] pairs of data
Alternatively:
\@x_column, \@y_column: two array references of data of equal length.
\@x_column is the x-axis data. \@y_column is the y-axis data.
Finally, data can be stored in a file.
Gnuplot now has the capability to read date/time data and to create
graphs which display date/time on any axis. Unfortunately, mechanism
for reading data is less sophisticated than the mechanism for writing
data. Chart::Graph::Gnuplot implements date/time data in the same
way as Gnuplot itself is presently implemented for consistency with
the application.
Any axis can be set to read date/time data instead of numerical
data. This is done by setting the options xdata, ydata,
x2data, or y2data to the value time. Unfortunately, you can
set only one format to read your data; therefore, consistency is
advised. The input format is set using the timefmt command noted
above. The timefmt command takes a string consisting of the
elements noted below.
Gnuplot uses the same format codes for date/time input and output so
the following table applies to both situations.
+---------+------------------------------------------------------------------+
| Format | Explanation |
+---------+------------------------------------------------------------------+
| %d | day of the month, 1--31 |
| %m | month of the year, 1--12 |
| %y | year, 0--99 |
| %Y | year, 4-digit |
| %j | day of the year, 1--365 |
| %H | hour, 0--24 |
| %M | minute, 0--60 |
| %S | second, 0--60 |
| %b | three-character abbreviation of the name of the month |
| %B | name of the month |
+---------+------------------------------------------------------------------+
In addition there are some additional special cases for reading
date/time data. To quote from Gnuplot manual: ``Any character is
allowed in the string, but must match exactly. \t (tab) is
recognized. Backslash-octals (\nnn) are converted to char. If there is
no separating character between the time/date elements, then %d, %m,
%y, %H, %M and %S read two digits each, %Y reads four digits and %j
reads three digits. %b requires three characters, and %B requires as
many as it needs.'' Gnuplot uses the space character as white space
pattern match - essentially the same as Perl's: \s*.
Gnuplot normally uses whitespace to separate datasets. However,
Gnuplot does recognize white space specified in the timefmt
string. So for example, x-y data can be specified in columns like
this:
25/01/2001 03:05:39 2.05e-5
The timefmt string required would be: "%d/%m/%y %H:%M:%S". Note
that while the month and month abbreviation can be accepted, any other
text must be matched (excluded) in the timefmt string. Certainly,
representing dates as numerically is probably the most conservative.
Creating date/time labels for any of the axes is basically analogous.
The Chart::Graph:Gnuplot global option is format, and it takes a
two element array reference: the axis to be plotted and the format
string. In addition to the time options listed above, format
supports the following additional codes for formatting the numerical
data on the axes.
+-------------+--------------------------------------------------------------+
| Format | Explanation |
+-------------+--------------------------------------------------------------+
| %f | floating point notation |
| %e or %E | exponential notation; an "e" or "E" before the power |
| %g or %G | the shorter of %e (or %E) and %f |
| %x or %X | hex |
| %o or %O | octal |
| %t | mantissa to base 10 |
| %l | mantissa to base of current logscale |
| %s | mantissa to base of current logscale; scientific power |
| %T | power to base 10 |
| %L | power to base of current logscale |
| %S | scientific power |
| %c | character replacement for scientific power |
| %P | multiple of pi |
+-------------+--------------------------------------------------------------+
As in the case of input there some additional options related to these
output formats. Again to quote the Gnuplot manual ``Other
acceptable modifiers (which come after the % but before the format
specifier) are -, which left-justifies the number; +, which
forces all numbers to be explicitly signed; #, which places a
decimal point after floats that have only zeroes following the decimal
point; a positive integer, which defines the field width; 0 (the
digit, not the letter) immediately preceding the field width, which
indicates that leading zeroes are to be used instead of leading
blanks; and a decimal point followed by a non-negative integer, which
defines the precision (the minimum number of digits of an integer, or
the number of digits following the decimal point of a float).''
Gnuplot also provides more flexibility in terms of the output format
codes available for date/time. In addition to those shared with
input, the following codes can be used for formatting output date/time
axes only.
+-------------+--------------------------------------------------------------+
| Format | Explanation |
+-------------+--------------------------------------------------------------+
| %a | abbreviated name of day of the week |
| %A | full name of day of the week |
| %b or %h | abbreviated name of the month |
| %B | full name of the month |
| %D | shorthand for "%m/%d/%y" |
| %H or %k | hour, 0--24 |
| %I or %l | hour, 0--12 |
| %p | "am" or "pm" |
| %r | shorthand for "%I:%M:%S %p" |
| %R | shorthand for %H:%M" |
| %T | shorthand for "%H:%M:%S" |
| %U | week of the year (week starts on Sunday) |
| %w | day of the week, 0--6 (Sunday = 0) |
| %W | week of the year (week starts on Monday) |
+-------------+--------------------------------------------------------------+
Finally, Chart::Graph::Gnuplot has an extension to support UNIX
timestamps. Note this not built into Gnuplot itself.
Users can access this option by setting the xrange using the uts
option instead. UNIX timestamps are only available on the x-axis at this
time. They cannot be used on y, x2, or y2. See the last example for more
details on using UNIX timestamps.
The following are four examples on how to use Chart::Graph::Gnuplot in
a variety of settings.
The following example illustrates most of the general capabilities of
Chart::Graph::Gnuplot. It creates the output file gnuplot1.png.
in the png graphics format. The data is coming from all three
sources. The first data source is a matrix, the second is a column,
and the last is an external data file.
use Chart::Graph::Gnuplot qw(gnuplot);
gnuplot({'title' => 'foo',
'x2-axis label' => 'bar',
'logscale x2' => '1',
'logscale y' => '1',
'output type' => 'png',
'output file' => 'gnuplot1.png',
'xtics' => [ ['small\nfoo', 10], ['medium\nfoo', 20], ['large\nfoo', 30] ],
'ytics' => [10,20,30,40,50],
'extra_opts' => 'set key left top Left'},
[{'title' => 'data1',
'type' => 'matrix'}, [[1, 10],
[2, 20],
[3, 30]] ],
[{'title' => 'data2',
'style' => 'lines',
'type' => 'columns'}, [8, 26, 50, 60, 70],
[5, 28, 50, 60, 70] ],
[{'title' => 'data3',
'style' => 'lines',
'type' => 'file'}, './samplefile'],);
gnuplot1.png
Gnuplot supports errorbars to aid in data interpretation. To use an
arbitrary number of data columns (for errorbars), set style to
errorbars and include extra data columns. The example below
produces the file gnuplot2.png
Note the following: These columns MUST be the the following formats:
(x, y, ydelta), (x, y, ylow, yhigh), (x, y, xdelta), (x, y,
xlow, xhigh), (x, y, xdelta, ydelta), or (x, y, xlow, xhigh,
ylow, yhigh) This will only work with data type columns. Also, you
MUST use the using option to specify how columns of the data file
are to be assigned to x, y, ydelta, ylow and yhigh,
xdelta, xlow and xhigh.
use Chart::Graph::Gnuplot qw(gnuplot);
gnuplot({"title" => "Examples of Errorbars",
"xrange" => "[:11]",
"yrange" => "[:45]",
"output file" => "gnuplot2.gif",
"output type" => "gif",
},
# dataset 1
[{"title" => "yerrorbars",
"style" => "yerrorbars",
"using" => "1:2:3:4",
"type" => "columns"},
[ 1, 2, 3, 4, 5, 6 ], # x
[ 5, 7, 12, 19, 28, 39 ], # y
[ 3, 5, 10, 17, 26, 38 ], # ylow
[ 6, 8, 13, 20, 30, 40 ] ], # yhigh
# dataset 2
[{"title" => "xerrorbars",
"style" => "xerrorbars",
"using" => "1:2:3:4",
"type" => "columns"},
[ 4, 5, 6, 7, 8, 9 ], # x
[ 1, 4, 5, 6, 7, 10 ], # y
[ 3.3, 4.4, 5.5, 6.6, 7.7, 8.8 ], # xlow
[ 4.1, 5.2, 6.1, 7.3, 8.1, 10 ] ], # xhigh
# dataset 3
[{"title" => "xyerrorbars",
"style" => "xyerrorbars",
"using" => "1:2:3:4:5:6",
"type" => "columns"},
[ 1.5, 2.5, 3.5, 4.5, 5.5, 6.5 ], # x
[ 2, 3.5, 7.0, 14, 15, 20 ], # y
[ 0.9, 1.9, 2.8, 3.7, 4.9, 5.8 ], # xlow
[ 1.6, 2.7, 3.7, 4.8, 5.6, 6.7 ], # xhigh
[ 1, 2, 3, 5, 7, 8 ], # ylow
[ 5, 7, 10, 17, 18, 24 ] ], # yhigh
# dataset 4
[{"title" => "xerrorbars w/ xdelta",
"style" => "xerrorbars",
"using" => "1:2:3",
"type" => "columns"},
[ 4, 5, 6, 7, 8, 9 ], # x
[ 2.5, 5.5, 6.5, 7.5, 8.6, 11.7 ], # y
[ .2, .2, .1, .1, .3, .3 ] ], # xdelta
# dataset 5
[{"title" => "yerrorbars w/ ydelta",
"style" => "yerrorbars",
"using" => "1:2:3",
"type" => "columns"},
[ .7, 1.7, 2.7, 3.7, 4.7, 5.7 ], # x
[ 10, 15, 20, 25, 30, 35 ], # y
[ .8, 1.2, 1.1, 2.1, 1.3, 3.3 ] ], # ydelta
# dataset 6
[{"title" => "dummy data",
"type" => "matrix"},
[ [1,1] ]],
# dataset 7
[{"title" => "xyerrorbars w/ xydelta",
"style" => "xyerrorbars",
"using" => "1:2:3:4",
"type" => "columns"},
[ 7.5, 8.0, 8.5, 9.0, 9.5, 10.0 ], # x
[ 30, 27, 25, 23, 27, 33 ], # y
[ .2, .1, .3, .6, .4, .3 ], # xdelta
[ .8, .7, .3, .6, 1.0, .3 ] ], # ydelta
);
gnuplot2.gif
As noted above, Chart::Graph::Gnuplot includes support for plotting
date and times as source data. the following shows how to plot data,
where the x-axis contains dates, and the y-axis contains stock prices
from a major computer major during the ``dot-com meltdown.'' For date
and time data that requires high precision, using UNIX time stamps is
probably the best solution (see below.) As used in the first example,
any option available to Gnuplot can be passed to Gnuplot using
the extra_opts option. This example uses this feature to enable two
options: a grid over the graph and a timestamp for when the graph was
created.
use Chart::Graph::Gnuplot qw(gnuplot);
#Debugging aid - save the temporary files if desired
#$Chart::Graph::save_tmpfiles = 1;
#Debugging aid - turn on extra debugging messages
#$Chart::Graph::debug = 1;
# Call and "usual" global parameters
gnuplot({'title' => 'Corporate stock values for a major computer maker',
'x-axis label' => 'Month and Year',
'y-axis label' => 'Stock price',
'output type' => 'png',
'output file' => 'gnuplot3.png',
# Setting date/time specific options.
'xdata' => 'time',
'timefmt' => '%m/%d/%Y',
'format' => ['x', '%m/%d/%Y'],
# Set output range - note quoting of date string
'xrange' => '["06/01/2000":"08/01/2001"]',
'extra_opts' => join("\n", 'set grid', 'set timestamp'),
},
# Data for when stock opened
[{'title' => 'open',
'type' => 'matrix',
'style' => 'lines',
},
[
['06/01/2000', '81.75'],
['07/01/2000', '52.125'],
['08/01/2000', '50.3125'],
['09/01/2000', '61.3125'],
['10/01/2000', '26.6875'],
['11/01/2000', '19.4375'],
['12/01/2000', '17'],
['01/01/2001', '14.875'],
['02/01/2001', '20.6875'],
['03/01/2001', '17.8125'],
['04/01/2001', '22.09'],
['05/01/2001', '25.41'],
['06/01/2001', '20.13'],
['07/01/2001', '23.64'],
['08/01/2001', '19.01'],
]
],
# Data for stock high
[{'title' => 'high',
'type' => 'matrix',
'style' => 'lines',
},
[
['06/01/2000', '103.9375'],
['07/01/2000', '60.625'],
['08/01/2000', '61.50'],
['09/01/2000', '64.125'],
['10/01/2000', '26.75'],
['11/01/2000', '23'],
['12/01/2000', '17.50'],
['01/01/2001', '22.50'],
['02/01/2001', '21.9375'],
['03/01/2001', '23.75'],
['04/01/2001', '27.12'],
['05/01/2001', '26.70'],
['06/01/2001', '25.10'],
['07/01/2001', '25.22'],
['08/01/2001', '19.90'],
]
],
# Data for stock close
[{'title' => 'close',
'type' => 'matrix',
'style' => 'lines',
},
[
['06/01/2000', '52.375'],
['07/01/2000', '50.8125'],
['08/01/2000', '60.9375'],
['09/01/2000', '25.75'],
['10/01/2000', '19.5625'],
['11/01/2000', '16.50'],
['12/01/2000', '14.875'],
['01/01/2001', '21.625'],
['02/01/2001', '18.25'],
['03/01/2001', '22.07'],
['04/01/2001', '25.49'],
['05/01/2001', '19.95'],
['06/01/2001', '23.25'],
['07/01/2001', '18.79'],
['08/01/2001', '18.55'],
]
]
);
gnuplot3.png
Chart::Graph::Gnuplot can convert Unix timestamps into normal dates
for x-axis values. Collisions with existing user x-tics are can be
remedied by prepending a literal '\n' (or ``\\n'') to their tic-labels.
The 'uts' option takes an array ref with 2 to 4 elements:
[ start_timestamp, end_timestamp, <scale>, <use_local_timezone> ]
If the optional element 'scale' is > 1 the number of tics will be reduced.
If the optional element 'use_local_timezone' is set to non-zero value
the local timezone is used, UTC is assumed otherwise.
The variables $Chart::Graph::Gnuplot::show_year and
$Chart::Graph::Gnuplot::show_seconds influence the formatting of the x-tics.
[...]
%options = (
'title' => 'uts example',
'output file' => 'gnuplot4.gif',
'output type' => 'gif',
'x2-axis label' => 'time',
'xtics' => [ ['\n9pm UTC', 954795600] ],
'ytics' => [10,20,30,40,50],
'extra_opts' => 'set nokey',
'uts' => [954791100, 954799300],
);
$plot = [{'title' => 'Your title',
'type' => 'matrix'},
[
[954792100, 10],
[954793100, 18],
[954794100, 12],
[954795100, 26],
[954795600, 13], # 21:00
[954796170, 23],
[954797500, 37],
[954799173, 20],
[954799300, 48],
],
];
gnuplot(\%options, $plot);
gnuplot4.gif
Note: The present implementation of UNIX time stamps only supports
assigning xtics for x-axis labels. Using the Gnuplot directive:
format is not supported.
Chart::Graph::Gnuplot supports the plotting of functions, this can
be mixed with other data-types:
my %options = (
'title' => 'plot functions example',
'output file' => 'gnuplot5.png',
);
my $data = [{ 'title' => 'data 1',
'style' => 'lines',
'type' => 'matrix',
},
[
[0,10],
[3,30],
[6,0],
[9,-10],
[12,-0],
]
];
my $fnc1 = [{ 'title' => 'function 1',
'style' => 'lines',
'type' => 'function',
},
'10*sin(x)+2*cos(1.1 * x)+.5*tan(x)'
];
my $fnc2 = [{ 'title' => 'function 2',
'style' => 'lines',
'type' => 'function',
},
'20*sin(sqrt(2**x))/sqrt(2**x)'
];
gnuplot(\%options, $data, $fnc1, $fnc2);
gnuplot5.png
This version of Chart::Graph::Gnuplot was tested against
Gnuplot Version 4.0 patchlevel 0, some features might not work
on older versions of gnuplot.
For more information on gnuplot, please see the gnuplot web page:
http://www.gnuplot.org/
Send email to graph-dev@caida.org is you have problems, questions,
or comments. To subscribe to the mailing list send mail to
graph-dev-request@caida.org with a body of "subscribe your@email.com"
CAIDA Perl development team (cpan@caida.org)
gnuplot(1).