IaGraphManual
This is a package of interactive graphing tools, built upon the Climate Data Analysis Tools (CDAT) suite produced by the Program for Climate Model Diagnosis and Intercomparison (PCMDI) at Lawrence Livermore National Laboratory (LLNL). The package will create line plots, scatter plots, and contour plots with a single line of Python code.
Sometimes the plot generated will also be suitable for publications, and procedures in this package will allow you to write those plots to a Postscript or GIF file, but usually you will want a more complex plot for publications, which this package cannot make. If you want a graphing package for Python that has more features, here are some you might want to look at: CDAT, ChartDirector, DISLIN, gmt, GracePlot, Matplotlib, and SciPy.
What distinguishes this package from other plotting packages for Python is the emphasis on graphing using a single line of Python code. Other packages do not require much more code (maybe 3-5 more lines), and in fact this package uses those other graphing packages to make its graphs. But for the purposes of interactive plotting, 3 lines is 2 lines too many. I try to emulate IDL (Interactive Data Language) syntax (though not IDL array indexing, since Python and IDL index their arrays completely differently).
The home page for the package contains the package license, installation and downloading instructions, a complete listing of package contents, help for the modules, and probably all the description and examples most users need to use the package. Most users can ignore this manual you're currently reading.
That being said, this manual describes the programming logic behind the package and also contains a more detailed description of the capabilities of this package.
The manual is subdivided into these categories:
Because the package is designed to be used for interactive plotting,
I use a procedural logic instead of object-oriented or functional.
Thus, all key commands are called as procedures instead of functions
or methods.
I also try to emulate the IDL direct graphics structure.
IaGraph is built upon CDAT's Visualization Control System (VCS).
VCS works by decomposing the elements of a graph into objects
and placing those objects onto a VCS canvas. Up to 8 VCS canvases
can be defined at one time in a Python session. In
IaGraph,
each time a graph is created
(e.g. with a
plot or
contour command), a new VCS canvas is created
onto which the plot is placed. This new canvas is then set
as the "active canvas" stored in the
IaGraph
"system variables" class (
Sysvar),
to enable us to manipulate the plot even after rendering.
Any previous active canvas stored in the system variables class
is cleared then overwritten when a new plot is created.
Note that since when a new plot is created the existing active
canvas is used, the new plot does not contribute to the 8 VCS canvas
limit. Only when a new window is opened
(using the
window command) and a plot made
in this new window is another VCS canvas initialized.
Besides storing the active canvas,
global control over many plot settings is accomplished through
Sysvar (which is defined in __init__.py).
The system variables are all class attributes of
Sysvar;
Sysvar has no
instance variables (although class attributes are changed
via a class instance). Thus, all system variables are available
once
IaGraph is imported, are available to all instances of
the class, and will persist as long as the Python session is open.
Admittedly, this is not very pretty and smacks of a Fortran
common block. It was, however, the only way I could think of
of allowing some level of global control over
IaGraph
plots.
The syntax of the
Sysvar class is similar
to IDL syntax. For instance, the main plotting system variables
in IDL (!P variables) are prefixed by
p_ in
Sysvar. Likewise, axes system variables (!X and !Y in IDL)
are prefixed by
x_ and
y_ in
Sysvar. Because
Sysvar attributes
are all class attributes it's best to refer to an attribute
with the
__class__ tag. Thus, if
sysvar (
= IaGraph.Sysvar()) is a
realization of
Sysvar, the x-axis VCS font
code is
sysvar.__class__.x_font.
The default values for a number of the parameters in the
plotting commands are all set as an attribute of
Sysvar.
Through system variables you can also control some aspects of
a plot that are not controllable via a procedure keyword, or to
directly supercede the internal defaults of a procedure.
Procedures generally use the following logic in deciding which
value to use for a parameter, if there is more than one choice:
None.
None, the value of the corresponding system variable is used.
None, the procedure assigns a local default setting for that parameter.
Note that
p_,
x_, and
y_
system variables are never (at least I think are never) changed by
an
IaGraph procedure.
The only system variables that are changed by
IaGraph procedure(s) are the
active_canvas,
active_canvas_base_gm,
active_canvas_base_tpl,
inactive_canvases,
inactive_canvases_base_gm, and
inactive_canvases_base_tpl
attributes.
A number of plot attributes can be controlled via
system variables, including: font and font height of
overall title, axes titles, and axes tick labels.
Sysvar also allows you to directly control which
ticks are labeled: set
[xy]_tickvalues. This
is particularly useful if you want to have non-numeric labels,
such as latitude/longitude values. For more information on
changing graphics properties via system variables see
here.
Remember, once you change the setting of a system variable,
that setting is retained for the rest of the Python session,
until it is changed again!
A full list of all
Sysvar attributes (and their
default values) is found here.
The precise rules of how a procedure chooses its parameter settings
can be viewed via the
help command for the procedure.
Plots are created and manipulated via procedures and either
create or operate on the active canvas, as stored in the
active_canvas attribute in the
Sysvar class.
There are 2 exceptions: the
loadct procedure and
helper functions.
The procedures that create an active canvas (and overwrite any
previously existing active canvas) are:
contour,
plot, and
plotct.
The procedures that operate on an active canvas (and do not change
anything in the active canvas) are:
active2gif and
active2ps.
The
loadct takes a VCS canvas and specified
color map index (passed in as the two positional arguments)
and sets the active color map for that canvas to the specified map.
For consistency with the rest of the package,
loadct should have operated on the
active canvas, but for some reason Python won't let me.
This workaround worked, so for this one key procedure I had
the canvas passed in as an argument.
Helper functions can be procedural or functional. Usually they
do tasks that are non-central to the package and thus are not
available with a
from IaGraph import * command.
One example of this is
wavelen2rgb which returns
an RGB triple given a wavelength of visible light. To use helper
functions, you'll have to import them via their full package/module
pathname. Thus, for
wavelen2rgb import it via:
import IaGraph.wavelen2rgb.wavelen2rgb as wavelen2rgb.
[Back up top to the Introduction.]
The
plot command creates both line and scatter plots,
since scatter plots are just line plots without the lines.
The default of
plot is to make a line plot with
solid connecting lines and a square as the plot symbol.
You can change the line type through the
linestyle
keyword and plot symbol through the
psym keyword.
To remove connecting lines, set
psym to a value greater
than zero. Negative
psym plots connecting lines and a
psym of 0 gives a line plot without any plot symbols.
Here are lists of the available plot symbols and line styles:
Note that for the "dash" linestyle, the VCS routine I use to dump plots to Postscript and GIF does not seem to reproduce the dash spacings as they appear on screen; the dashes are much closer together in the Postscript and GIF versions. Thus, I'd recommend you use "long-dash" if you want a readable dash.
Plot symbol size is controlled by the
symht keyword.
The default value of 7 gives squares that have an approximate
on-screen size of 2 mm.
Keywords shared in common between
plot and other
plotting procedures (e.g.
contour) are described
here.
The
plot procedure is
somewhat special in that while CDAT is the dependency you
wish to have in order to get full performance from the
routine,
plot will still provide some
functionality if you only have
Grace
and
gracePlot
installed, or even if you only have
the Tk widgets in the
ScientificPython package installed.
See the help for
plot
for details.
[Back up top to the Introduction.]
The
contour command can produce three types of
contour plots: plots with contour lines only, plots with
smooth, filled contours, and plots with both filled contours
and lines overlain.
When contour lines are plotted, negative contours are long-dashed and
positive contours are solid.
Contour defaults to plotting both filled contours
with lines overlain, along with a color bar key below the plot.
Obviously if only contour lines are plotted, there's no color bar
key plotted. If you are doing filled contours and wish to suppress
the color bar, set keyword
colorbar to 0.
The procedure defaults to automatically calculate contours for you.
The system variable
p_maxnlev sets
the maximum number of level intervals that will be allowed
in this automatically calculation.
If you want specific keywords, specify them
through the
c_levels keyword.
You can choose which color table to use in the filled contours
via the
ctindex keyword. The command
loadct() will list all available values.
The default is 13 (rainbow, violet to red, 390-680 nm).
Continents are turned off by default. To plot outlines of modern
continents, set the
continents keyword to a non-zero
value.
[Back up top to the Introduction.]
The procedure
loadct will set a color map for the
VCS canvas that is passed into
loadct. All plotting
procedures that use a color map (e.g.
contour) set
the active color map using
loadct; the color map
is specified to the plotting routine
via the
ctindex keyword.
A list of the color maps defined in
loadct is found
here.
If you wish to add your own color map,
I'd suggest you just hack the code for
loadct.
Just add an additional
elif statement after the
elif block that selects the default color map
(i.e. after the "
elif cmap_index == 99:" statement).
In your new
elif block, assign a color map index to
be the
loadct reference to your color map, and set all
values of
loadct_cmap.index[i] to RGB triples, for
indices
i from 16 to 239, inclusive.
[Back up top to the Introduction.]
The active canvas (stored in system variable
active_canvas)
can be written to a
Postscript file using
active2ps and a
GIF file using
active2gif.
The
active2ps routine writes the plot to landscape.
The
active2gif routine also writes to landscape.
However, the GIF file is not rotated 90 degrees like the Postscript
file is, so you can view the file without having to rotate the image.
Both routines will replace any prexisting graphics file of
the same name.
[Back up top to the Introduction.]
plotct:
Produces a plot of a
loadct color table, with values
of color indices shown. You can use this to visualize what the
color map you're using will look like. This procedure creates a
new plot and overwrites and existing active canvas.
[Back up top to the Introduction.]
The
plot and
contour procedures
share some keywords. Here we describe how to use those keywords:
annot:
The placement of axes titles and the overall title is pretty
standard, and so I won't discuss them. However, I've added an
additional annotation feature to the plot generation
routines (e.g.
plot,
contour) that
I think I should probably explain a little. Often I like to add
additional information about what a plot contains, how it was made,
etc.; this information
I plot out at the top of the page in small type. The
annot
keyword enables you to include such text.
If the keyword is defined, the default values of
position adjust to give you more space
at the top of the page to add the annotation. The
size of the plot isn't changed, but the location on the
page is.
position:
The position of the plot on the page can be moved by the
position keyword or its system variable
equivalent. This keyword is a
4-element list [bbllx, bblly, bburx, bbury] of
the bounding box (x,y) coordinates in normalized values. The
data origin is the lower-left corner, and the upper-right corner
of the data box is the upper-right corner of position.
[xy]range:
The
xrange and
yrange keywords allow
you to control what part of the x- and y-axes are plotted.
Each keyword accepts a 2-element list of minimum and maximum
values specifying the interval.
Note that these keywords set the range of the
[xy]-axis used to calculate "neat" tickmarks,
from which the actual axis range is set;
depending on what the
[xy]range values
are, the actual plot range may look different.
If you want the range to be precisely certain values,
set them through the
[xy]_tickvalues
system variable.
The
[xy]_range
system variables do the same thing as the
[xy]range keywords.
If you wish to directly control axis tick labels, set the
[xy]_tickvalues system variable.
title:
String scalar specifying the overall title.
[xy]title:
String scalar specifying the [xy]-axis title.
A number of graphics attributes, besides those with an equivalent
graphics keyword (noted above), can be controlled via system variables.
The programming logic of systems variables is described
here.
The
Sysvar class
docstring documentation
provides enough details (along with a list of the default values)
for most of the variables.
Here we describe how to change graphics settings for system variables
that could use some more description.
In all the examples given, we assume that:
is an instance of theis an instance of the
sysvar = IaGraph.Sysvar()
Sysvarclass. Remember, since all system variables are
Sysvarclass attributes it is good practice to refer to those attributes with the
__class__attribute, e.g.
sysvar.__class__.p_font.
Font Type and Height:
p_font changes the font of the overall title, while
[xy]_font sets the font of the axes text. The font
code is an integer that follows the VCS code for font.
The height is set for overall graphics and the axes text
through the
p_fontht and
[xy]_fontht
system variables, respectively. This is an integer and is in
arbitrary units. You can approximately convert these values to
normalized units by multiplying by
p_fontht2norm.
A setting of 40 font height units gives capital letters that
are approximately 1/4 inch on screen (assuming landscape orientation
output).
Ticks:
The
p_ticklen variables gives general tick lengths,
in normalized units. Axes tick lengths are specified by
[xy]_ticklen.
The plotting routines, by default, calculate the number of tick
marks based upon a "nice" division of the axes ranges. The
maximum number of ticks that will be allowed in this default
calculation is controlled by
[xy]_tickmaxnum.
You can also directly set the x- and y-axis tick labels
through
[xy]_tickvalues. This system variable
is a dictionary where the dictionary key is the tick marks'
numerical value and the dictionary value is a string labeling
each tick mark.
Remember, once you change the setting of a system variable,
that setting is retained for the rest of the Python session,
until it is changed again!
Thus, if you change the font height system variable, all
subsequent
IaGraph plots made during that Python session
will use that height.
[Back up top to the Introduction.]
The code is pretty well-commented, so you should be able to read it to figure out what it does. However, there are a few design decisions I made that I thought I should point out.
The first one I wanted to point out because it could result in you running out of memory if you make a zillion plots. Because every time you make a plot you need to create a whole bunch of VCS objects, the question comes what you should name these objects. A static name isn't any good, because if you have a multiplicity of plots, there's no guarantee that each plot's object of the same name will be identical (in fact, the reverse is usually true). And since I wanted the capability of being able to go back to any plot in memory at will and revising it (which requires all component objects to remain defined for the duration of the plot's life), I needed to create a naming system that gave every VCS object a unique name. (Additionally, I couldn't figure out a way to remove a name from the VCS object list, if the object itself isn't defined, so even if I saved the names of all VCS objects I wanted removed, I couldn't remove them because the local objects that instantiated the list entry are undefined after the procedure exits.)
Thus, the VCS objects created by
IaGraph all have a suffix based
upon the system time, in fraction of
a second. The suffix is long enough to guarantee no reuse of names
for at least 100 days; as long as the Python session is closed before
then, every name will be guaranteed to be unique.
Unfortunately, as long as you don't close your Python session, all VCS objects created during that session will remain defined. If you make many plots, this could result in many VCS objects being created, which may result in you running out of memory. I don't know when this limit is reached; no problems resulted when I made 100 consecutive simple x-y plots in one window during one session on my modest Linux box (which has 255 Mb memory and 498 Mb swap).
The second design decision regards the names of the graphics
method and template objects (again here I mean the name that shows
up in a
show method, not the name of an object instance).
In the all the routines of the package, I assume the following is true:
plotand
oplotare xvsy graphics methods and have names beginning with the string 'xygm'. The exception is when
oplotis called for no connecting lines, in which case the graphics method created is the scatter method. However, the name still begins 'xygm'.
plotand
oplothave names beginning with the string 'mytpl'.
contourand
ocontourfor isofill plots have names beginning with the string 'fillgm'.
contourand
ocontourfor isofill plots have names beginning with the string 'filltp'.
contourand
ocontourfor isoline plots have names beginning with the string 'linegm'.
contourand
ocontourfor isoline plots have names beginning with the string 'linetp'.
The third decision was to store the names
of the base graphics method and template used on a canvas as
a system variable.
By "base" I mean the graphics method and template used when
the plot was first created (e.g. by a
plot or
contour command). I stored these values as
system variables in order to retrieve the
definitions of plot range, and other settings, for overplots.
Finally, the
plot command uses the xvsy graphics
method for both the cases when you have connecting lines and
when you do not. I do this by assuming the background color is
white and setting the line color to white when you have the case
of no connecting lines. However, since
oplot might
be plotting over a filled contour plot, in
oplot
I do not assume that the background color is white
and go through the extra work of
using the scatter graphics method
to take care of the case when there are no connecting lines.
[Back up top to the Introduction.]
Here's a list of some glitches that periodically arise. I list these separately from my bugs list since they're not worth fixing and reasonably easy to work-around.
[Back up top to the Introduction.]
Here's a partial list of improvements that need to be made in this package:
[xy]stylekeywords.
plotand
contourto read in axes from just an MV data object. For
plotgenerate an x-axis if only a single vector is passed in.
[Back up top to the Introduction.]
Copyright © 2003-2004.]
Return to IaGraph Home Page.
Return to Johnny Lin's Python Library.
Updated: June 16, 2004 by Johnny Lin <email address>.Updated: June 16, 2004 by Johnny Lin <email address>.