pywws.plot
Plot graphs of weather data according to an XML recipe
usage: python -m pywws.plot [options] data_dir temp_dir xml_file output_file
options are:
-h or --help display this help
data_dir is the root directory of the weather data
temp_dir is a workspace for temporary files e.g. /tmp
xml_file is the name of the source file that describes the plot
output_file is the name of the image file to be created e.g. 24hrs.png
Introduction
Like pywws.template
this is one of the more difficult to use
modules in the weather station software collection. It plots a graph (or
set of graphs) of weather data. Almost everything about the graph is
controlled by an XML file. I refer to these files as templates, but they
aren’t templates in the same sense as pywws.template
uses to
create text files.
Before writing your own graph template files, it might be useful to look at some of the examples in the example_graph_templates directory. If (like I was) you are unfamiliar with XML, I suggest reading the W3 Schools XML tutorial.
Text encoding
The [config]
section of weather.ini has
a gnuplot encoding
entry that sets the text encoding pywws uses to
write a gnuplot command file. The default value, iso_8859_1
, is
suitable for most western European languages, but may need changing if
you use another language. It can be set to any text encoding recognised
by both the Python codecs
module and the gnuplot set encoding
command.
If Python and gnuplot have different names for the same encoding, give
both names separated by a space, Python name first. For example:
[config]
gnuplot encoding = koi8_r koi8r
Note that you need to choose an encoding for which gnuplot
has a
suitable font. You may need to set the font with a terminal element.
Note also that this encoding is unrelated to the encoding of your XML
graph file, which is set in the XML header.
XML graph file syntax
Here is the simplest useful graph template. It plots the external temperature for the last 24 hours.
<?xml version="1.0" encoding="ISO-8859-1"?>
<graph>
<plot>
<subplot>
<title>Temperature (°C)</title>
<ycalc>data['temp_out']</ycalc>
</subplot>
</plot>
</graph>
In this example, the root element graph has one plot element, which has one subplot element. The subplot element contains a title element and a ycalc element. To plot more data on the same graph (for example dew point and temperature), we can add more subplot elements. To plot more than one graph (for example wind speed is measured in different units from temperature) in the same file we can add more plot elements.
The complete element hierarchy is shown below.
graph
This is the root element of the graph XML file. It does not have to be called “graph”, but there must be exactly one root element.
plot
Every graph element should contain at least one plot element. A separate graph is drawn for each plot element, but all share the same X axis.
start
This element sets the date & time of the start of the X axis. It is
used in the replace
method of a Python datetime object that is
initialised to 00:00 hours on the date of the latest weather station
hourly reading. For example, to start the graph at noon (local time)
on Christmas day 2008: <start>year=2008, month=12, day=25,
hour=12</start>
or to start the graph at 2am (local time) today:
<start>hour=2</start>
. The default value is (stop - duration).
New in version 14.06.dev1238: previously the <start>
and <stop>
elements were used in a
datetime constructor, so year
, month
and day
values
were required.
stop
This element sets the date & time of the end of the X axis. It is used
in the replace
method of a Python datetime object, just like
<start>
. The default value is (start + duration), unless start is
not defined, in which case the timestamp of the latest weather station
hourly reading is used.
duration
This element sets the extent of the X axis of the graph, unless both
start and stop are defined. It is used in the constructor of a Python
timedelta object. For example, to plot one week:
<duration>weeks=1</duration>
. The default value is hours=24.
layout
Controls the layout of the plots. Default is a single column. The
layout element specifies rows and columns. For example: <layout>4,
2</layout>
will use a grid of 4 rows and 2 columns.
size
Sets the overall dimensions of the image file containing the graph.
Default (in a single column layout) is a width of 600 pixels and
height of 200 pixels for each plot, so a graph with four plot elements
would be 600 x 800 pixels. Any size element must include both width
and height. For example: <size>800, 600</size>
will produce an
image 800 pixels wide and 600 pixels high.
fileformat
Sets the image format of the file containing the graph. Default is
png
. Any string recognised by your installation of gnuplot should
do. For example: <fileformat>gif</fileformat>
will produce a GIF
image.
If your installation of gnuplot supports it, pngcairo
is an
alternative to png
that can yield much better looking results.
New in version 15.11.0.dev1331: You can also set terminal options in this string, for example:
<fileformat>pngcairo font "arial,8" rounded</fileformat>
will use
a small “Arial” font and round the ends of line segments.
terminal
Allows complete control of gnuplot’s “terminal” settings. You may want
to use this if you are plotting to an unusual image format. Any string
recognised by your installation of gnuplot’s ‘set terminal’ command
should do. For example: <terminal>svg enhanced font "arial,9" dynamic
rounded size 600,800</terminal>
. This setting overwrites both size
and fileformat.
Changed in version 15.11.0.dev1331: The size and fileformat elements are now the preferred way to set the gnuplot “terminal”.
lmargin
Sets the left margin of the plots, i.e. the distance from the left hand axis to the left hand edge of the image area. According to the gnuplot documentation the units of lmargin are character widths. The default value is 5, which should look OK in most circumstances.
rmargin
Sets the right margin of the plots, i.e. the distance from the right hand axis to the right hand edge of the image area. According to the gnuplot documentation the units of rmargin are character widths. The default value is -1, which sets automatic adjustment.
xformat
Sets the format of the time / date xtic labels. The value is a strftime style format string. Default depends on the graph duration: 24 hours or less is “%H%M”, 24 hours to 7 days is “%a %d” and 7 days or more is “%Y/%m/%d”.
xlabel
Sets the X axis label. The value is a strftime style format string. Default depends on the graph duration: 24 hours or less is “Time (%Z)”, 24 hours to 7 days is “Day” and 7 days or more is “Date”. The datetime used to compute this is start, which may produce unexpected results when a graph spans DST start or end.
dateformat
Sets the format of the date labels at each end of X axis. The value is
a strftime style format string. Default is “%Y/%m/%d”. The right
hand label is only drawn if it differs from the left. To have no
labels, set an empty format: <dateformat></dateformat>
xtics
Sets the spacing of the “tic” marks on the X axis. The value is an integer number of hours. The default is to allow gnuplot to set an appropriate interval.
title
Sets the title of the graph. A single line of text, for example:
<title>Today's weather</title>
. This title appears at the very top
of the graph, outside any plot area.
New in version 15.06.0.dev1301: If the title contains any “%” characters it will be used as a strftime style format string for the datetime of the stop value. This allows you to include the graph’s date or time in the title.
subplot
Every plot element should contain at least one subplot element. A separate trace is drawn for each subplot element, but all share the same X and Y axes.
bmargin
Sets the bottom margin, i.e. the spacing between the lower X axis and the edge of the graph (or the next plot). The default is to let gnuplot adjust this automatically, which works OK most of the time but you may wish to fine tune the value to suit your installation.
The permitted value is any non-negative real number. On my setup 0.9
is a good value, set as follows: <bmargin>0.9</bmargin>
.
yrange
Sets the lower and upper limits of the (left hand) Y axis. The value
is anything understood by gnuplot, typically a pair of numbers. The
default is to allow gnuplot to set appropriate values, which is
unlikely to be what you want. For example, to plot typical UK
temperatures with no value going off the graph: <yrange>-10,
30</yrange>
. Note that commas are converted to colons, so
<yrange>-10:30</yrange>
would be equivalent.
You can use an asterisk to have gnuplot choose a suitable value. For
example, to have the upper value auto scale whilst fixing the lower
value at zero, use <yrange>0:*</yrange>
.
Since gnuplot version 4.6 you can set lower and/or upper bounds of the
auto scaled range. The gnuplot syntax for this is lo < * < hi
, but
as the plot template is an XML file we need to replace the <
characters with <
. For example, if we want the upper value to
always be 20 or more we can use <yrange>0:20 < *</yrange>
.
y2range
Sets the lower and upper limits of the right hand Y axis. Default is for the right hand Y axis to be the same as the left, but setting a different range is useful in dual axis plotting.
ytics
Controls the “tic” marks on the left hand Y axis. The value can be
anything that’s understood by gnuplot. For example, to set the tic
spacing to 45 use <ytics>45</ytics>
. More complex things are also
possible, e.g. to label a wind direction graph with compass points,
use <y2tics>('N' 0, 'E' 90, 'S' 180, 'W' 270, 'N' 360)</y2tics>
.
y2tics
Controls the “tic” marks on the right hand axis. The format is the same as that for ytics. Default behaviour is to copy the left hand tic marks, but without labels.
ylabel
Adds a label to the (left hand) Y axis. For example, when plotting
temperature: <ylabel>°C</ylabel>
. If you use ylabel you will
probably want to adjust lmargin.
ylabelangle
Adjust the angle of the (left hand) Y axis label, if your version of
gnuplot supports it. For example, to write the label horizontally:
<ylabelangle>90</ylabelangle>
.
y2label
Adds a label to the right hand Y axis. For example, when plotting
humidity: <y2label>%</y2label>
. This is mostly used when plotting
dual axis graphs. If you use y2label you will probably want to adjust
rmargin.
y2labelangle
Adjust the angle of the right hand Y axis label, if your version of
gnuplot supports it. For example, to write the label horizontally:
<y2labelangle>90</y2labelangle>
.
grid
Adds a grid to the plot. In most situations gnuplot’s default grid is
suitable, so no value is needed: <grid></grid>
. More control is
possible using any of the options understood by gnuplot’s set grid
command. For example, to have horizontal grid lines only:
<grid>ytics</grid>
.
source
Select the weather data to be plotted. Permitted values are
<source>raw</source>
, <source>hourly</source>
,
<source>daily</source>
and <source>monthly</source>
. Default
is raw. Note that the different sources have different data
dictionaries, so this choice affects ycalc.
boxwidth
Sets the width of the “boxes” used when drawing bar graphs. The value is an integer expression yielding a number of seconds. Default depends on source: raw is 240, hourly is 2800 and daily is 2800 * 24.
title
Sets the title of the plot. A single line of text, for example:
<title>Temperature (°C)</title>
. This title appears within the
plot area, above any subplot titles.
command
Execute any gnuplot command, just before the main “plot” command. This
option allows advanced users to have greater control over the graph
appearance. The value is any valid gnuplot command, typically
beginning with the word set. For example: <command>set key tmargin
center horizontal width 1 noreverse enhanced autotitles box linetype
-1 linewidth 1</command>
. (Don’t ask me what this example does — I’m
not an advanced user).
New in version 15.11.0.dev1333: This element can be repeated to allow several things to be set.
xcalc
Controls the X axis positioning of plotted data values. The default
value of data[‘idx’] is correct for most data, but there are some
exceptions. For example, when plotting bar charts of hourly rainfall,
it’s nice to centre the bars on 30 minutes past the hour:
<xcalc>data['idx'].replace(minute=30, second=0)</xcalc>
.
ycalc
Selects the data to be plotted. Any one line Python expression that
returns a single float value can be used. At its simplest this just
selects one value from the “data” dictionary, for example:
<ycalc>data['temp_out']</ycalc>
plots the external temperature.
More complex expressions are possible, and some helper functions are
provided. For example: <ycalc>dew_point(data['temp_out'],
data['hum_out'])</ycalc>
plots the external dew point, and
<ycalc>wind_mph(data['wind_ave'])</ycalc>
plots the average wind
speed in miles per hour.
In addition to the functions in the pywws.conversions
module
there are four more useful functions: rain_hour(data)
returns the
amount of rain in the last hour, rain_day(data)
returns the amount
of rain since midnight (local time), rain_24hr(data)
returns the
amount of rain in the last 24 hours, and hour_diff(data, key)
returns the change in data item key
over the last hour.
Cumulative plots are also possible. The result of each ycalc
computation is stored and made available to the next computation in
the variable last_ycalc. This can be used with any data, but is most
useful with rainfall: <ycalc>data['rain'] + last_ycalc</ycalc>
.
A special case are plots with <style>candlesticks</style>
or
<style>candlesticksw</style>
which need 4 values in a specific
order: <ycalc>(data['temp_out_min_ave'], data['temp_out_min_lo'],
data['temp_out_max_hi'], data['temp_out_max_ave'])</ycalc>
. To add
a median bar, use another candlesticks plot with
data['temp_out_ave']
in all 4 fields.
axes
Selects which Y axis the data is plotted against. Default is the left
hand axis, but the right hand axis can be chosen with:
<axes>x1y2</axes>
. This can be used in conjunction with y2range to
plot two unrelated quantities on one graph, for example temperature
and humidity.
style
Sets the line style for the graph. Default is a smooth continuous
line, thickness 1. To select a bar graph use: <style>box</style>
.
To select points without a connecting line use: <style>+</style>
or <style>x</style>
. To select a line thickness 3 (for example)
use: <style>line 3</style>
. The thickness of points can be set in
a similar fashion. For complete control (for advanced users) a full
gnuplot style can be set: <style>smooth unique lc 5 lw 3</style>
.
For candlesticks plots you can specify line thickness as well, e.g.
<style>candlesticks 1.5</style>
. If you add whiskerbars, you can
change the width of the whiskerbars with a second parameter, e.g.
<style>candlesticksw 2 0.5</style>
would plot the whiskerbars with
50% width of the candlesticks.
colour
Sets the colour of the subplot line or boxes. This can be in any form
that gnuplot accepts, typically a single integer or an rgb specification
such as rgb "cyan"
or rgb "FF00FF"
. The mapping of integer
values to colours is set by gnuplot. Default value is an ever
incrementing integer.
title
Sets the title of the subplot. A single line of text, for example:
<title>Temperature (°C)</title>
. This title appears within the
plot area, next to a short segment of the line colour used for the
subplot.
Detailed API
Functions
|
Classes
|
|
|
|
|
|
|
Comments or questions? Please subscribe to the pywws mailing list http://groups.google.com/group/pywws and let us know.