\documentclass[twoside]{book}
\usepackage{graphicx}
\usepackage{color}
\usepackage{graphics}
\usepackage{listings}
\usepackage{natbib}
\usepackage{fullpage}
\usepackage{amssymb}
\usepackage{verbatimfiles}
\usepackage{url}
\usepackage[width=0.75\textwidth]{caption}
\usepackage{ae,aecompl}
\usepackage[bookmarks,colorlinks=true]{hyperref}
\usepackage{pslatex}
%\usepackage{html}
\definecolor{lightgray}{gray}{0.9}
\title{The Matplotlib User's Guide}
\author{John Hunter\\and\\Darren Dale}
\begin{document}
\lstset{
language=Python,
basicstyle=\small,
commentstyle=\color{blue},
stringstyle=\ttfamily,
showstringspaces=false,
backgroundcolor=\color{lightgray},
frame=single,
framerule=0pt,
emph = {axes, axis, bar, cla, clf, clim, close, cohere, colorbar,
colors, csd, draw, errorbar, figimage, figlegend, figtext, figure,
fill, gca, gcf, gci, get, get_current_fig_manager,
get_plot_commands, gray, grid, hist, hlines, hold, imshow, jet,
legend, load, loglog, pcolor, pcolor_classic, plot, plot_date,
plotting, psd, raise_msg_to_str, rc, rcdefaults, save, savefig,
scatter, scatter_classic, semilogx, semilogy, set, specgram, stem,
subplot, table, text, title, vlines, xlabel, ylabel},
emphstyle = \color{black}, % color for matplotlib funcs
breaklines=true,
breakatwhitespace = true,
postbreak = \space\dots
}
\newcommand{\fig}[4]
{\begin{figure}[ht]
\begin{center}
\includegraphics[width=#1]{#2}
\caption{\label{#4} #3}
\end{center}
\end{figure}}
\newcommand{\matlab}[0]{MATLAB{\texttrademark}}
\newcommand{\fname}[1]{{\tt #1}}
\newcommand{\func}[1]{{\tt #1}}
\newcommand{\class}[1]{{\tt #1}}
\newcommand{\mpldoc}[1]{{\tt #1}}
\newcommand{\code}[1]{{\tt #1}}
\newcommand{\prompt}[1]{\code{>>> #1}}
\newcommand{\carg}[1]{\textit{#1}} % command argument
\newcommand{\val}[1]{\textit{#1}}
\newcommand{\rc}[1]{{\tt #1}}
% a pointer to matplotlib documentation
\maketitle
\tableofcontents
\chapter{Introduction}
\label{cha:introduction}
matplotlib is a library for making 2D plots of arrays in python.
Although it has its origins in emulating the \matlab\ graphics
commands, it does not require \matlab, and can be used in a pythonic,
object oriented way. Although matplotlib is written primarily in pure
python, it makes heavy use of {NumPy} and other extension
code to provide good performance even for large arrays.
matplotlib is designed with the philosophy that you should be able to
create simple plots with just a few commands, or just one! If you
want to see a histogram of your data, you shouldn't need to
instantiate objects, call methods, set properties, and so it; it
should just work.
For years, I used to use \matlab\ exclusively for data analysis and
visualization. \matlab\ excels at making nice looking plots easy. When
I began working with EEG data, I found that I needed to write
applications to interact with my data, and developed and EEG analysis
application in \matlab. As the application grew in complexity,
interacting with databases, http servers, manipulating complex data
structures, I began to strain against the limitations of \matlab\ as a
programming language, and decided to start over in python. python
more than makes up for all of matlab's deficiencies as a programming
language, but I was having difficulty finding a 2D plotting package
(for 3D VTK more than exceeds all of my needs).
When I went searching for a python plotting package, I had several
requirements:
\begin{itemize}
\item Plots should look great - publication quality. One important
requirement for me is that the text looks good (antialiased, etc)
\item Postscript output for inclusion with \TeX\ documents
\item Embeddable in a graphical user interface for application
development
\item Code should be easy enough that I can understand it and extend
it.
\item Making plots should be easy.
\end{itemize}
\noindent Finding no package that suited me just right, I did what any
self-respecting python programmer would do: rolled up my sleeves and
dived in. Not having any real experience with computer graphics, I
decided to emulate \matlab's plotting capabilities because that is
something \matlab\ does very well. This had the added advantage that
many people have a lot of \matlab\ experience, and thus they can quickly
get up to steam plotting in python. From a developer's perspective,
having a fixed user interface (the pylab interface) has
been very useful, because the guts of the code base can be redesigned
without affecting user code.
The matplotlib code is conceptually divided into three parts: the
\textit{pylab interface} is the set of functions provided by
\mpldoc{matplotlib.pylab} which allow the user to create plots with
code quite similar to \matlab\ figure generating code. The
\textit{matplotlib frontend} or \textit{matplotlib API} is the set of
classes that do the heavy lifting, creating and managing figures, text,
lines, plots and so on. This is an abstract interface that knows
nothing about output. The \textit{backends} are device dependent
drawing devices, aka renderers, that transform the frontend
representation to hardcopy or a display device. Example backends: PS
creates postscript hardcopy, SVG creates scalar vector graphics
hardcopy, Agg creates PNG output using the high quality antigrain
library that ships with matplotlib - \url{http://antigrain.com}, GTK
embeds matplotlib in a GTK application, GTKAgg uses the antigrain
renderer to create a figure and embed it a GTK application, and so on
for WX, Tkinter, FLTK\dots.
matplotlib is used by many people in many different contexts. Some
people want to automatically generate postscript files to send to a
printer or publishers. Others deploy matplotlib on a web application
server to generate PNG output for inclusion in dynamically generated
web pages. Some use matplotlib interactively from the python shell in
Tkinter on windows. My primary use is to embed matplotlib in a GTK
EEG application that runs on windows, linux and OS~X.
Because there are so many ways people want to use a plotting library,
there is a certain amount of complexity inherent in configuring the
library so that it will work naturally the way you want it to. Before
diving into these details, let's first explore matplotlib's simplicity
by comparing a typical matplotlib script with its analog in \matlab.
{--- JDH}
\section{Migrating from \matlab}
\label{sec:migrating}
Using matplotlib should come naturally if you have ever plotted with
\matlab\, and should be fairly straightforward if you haven't. Like all
interpreted languages used for serious number crunching, python has an
extension module for processing numeric arrays. NumPy comes with many
\matlab-compatible analysis functions, which matplotlib extends. The
example code below shows two complete scripts: on the left hand side is
python with matplotlib, and on the right is \matlab.
\fig{4in}{figures/psd_matlab}{Colored noise signal and power spectrum
generated with \matlab\ as shown in Listing~\ref{lst:versus_matlab}.
Compare with matplotlib in Figure~\ref{fig:psd_py}.}{fig:psd_matlab}
Both scripts do the same thing: generate a white noise vector,
convolve it with an exponential function, add it to a sine wave, plot
the signal in one subplot and plot the power spectrum in another.
\begin{lstlisting}[caption={matplotlib and \matlab}, label=lst:versus_matlab]
# python % matlab
from pylab import * % no import necessary
dt = 0.01 dt = 0.01;
t = arange(0,10,dt) t = [0:dt:10];
nse = randn(len(t)) nse = randn(size(t));
r = exp(-t/0.05) r = exp(-t/0.05);
cnse = conv(nse, r)*dt cnse = conv(nse, r)*dt;
cnse = cnse[:len(t)] cnse = cnse(1:length(t));
s = 0.1*sin(2*pi*t) + cnse s = 0.1*sin(2*pi*t) + cnse;
subplot(211) subplot(211)
plot(t,s) plot(t,s)
subplot(212) subplot(212)
psd(s, 512, 1/dt) psd(s, 512, 1/dt)
\end{lstlisting}
The major differences are 1) NumPy has a function for creating
arrays (\func{arange} above) whereas \matlab\ has the handy notation
\code{[0:dt:10]}, 2) Python uses square brackets rather than
parentheses for array indexing, and there are some small differences
in how to do array lengths, sizes, and indexing. But the differences are
minute compared to the similarities: 1) \matlab\ and NumPy both do
array processing and have a variety of functions that efficiently
operate on arrays and scalars, 2) moderately sophisticated signal
processing (white noise, convolution, power spectra) is achieved in
only a few lines of clear code and 3) plots are simple, intuitive and
attractive (compare Figures~\ref{fig:psd_matlab} and
Figures~\ref{fig:psd_py}).
\fig{4in}{figures/psd_py}{Colored noise signal and power spectrum
generated with python matplotlib as shown in
Listing~\ref{lst:versus_matlab}. Compare with \matlab\ in
Figure~\ref{fig:psd_matlab}. Note that the waveforms are not
identical because they were generated from random
signals!}{fig:psd_py}
Hopefully, this example will have instilled some confidence in those who
have previously worked with \matlab\ that migrating to Python is not too
daunting a task. However, this guide will not attempt to serve as an
introduction to Python itself, and therefore assumes you already have a
rudimentary knowledge of the language. For users who are new to Python,
we recommend getting accustomed to the language by experimenting with
some of the tutorials at
\url{http://wiki.python.org/moin/BeginnersGuide/Programmers}.
Finally, matplotlib does not intend to meet the needs of \matlab\ users
alone. Many matplotlib users previously worked with gnuplot, for example,
and have influenced matplotlib's features based on their previous
experience. Our goal is to provide a flexible, powerful library that is
capable of easily producing beautiful plots for scientists and engineers
who work with Python.
\chapter{Installation and Setup}
\label{ch:setup}
\section{Installing}
\label{sec:installing}
Matplotlib is known to work on linux, unix, win32 and OS~X platforms.
This chapter will begin with basic installation instructions to help new
users get going quickly. The suggested setup for matplotlib version
0.87.7 and later requires python 2.3 or later, NumPy 1.0 or
later and freetype. To get the most out of matplotlib, you should also
install IPython and at least one of the GUI toolkits. We suggest using
the Tk GUI toolkit if you are just getting started.
\subsection{Quickstart on windows}
If you don't already have python installed, you may want to consider
using the enthought edition of python, which includes everything you
need to start plotting with matplotlib. Enthought's Python distribution
also includes a lot of other goodies, like the wxPython GUI toolkit and
SciPy - see \url{http://www.enthought.com/python} .
For standard Python installations, you should install NumPy before running
the matplotlib installer. The windows installer (*.exe) on the download
page contains everything else you need to get up and running. We highly
recommend installing PyReadline and IPython as well,
(see \url{http://ipython.scipy.org}).
There are many examples that are not included in the windows installer.
They can be found at
\url{http://matplotlib.sourceforge.net/matplotlib_examples_0.87.7.zip} .
\subsection{Package managers: (rpms, apt, fink)}
\subsubsection{RPMS}
\label{sec:rpms}
To build all the backends on a binary linux distro such as redhat, you
need to install a number of the devel libs (and whatever dependencies
they require), I suggest
\begin{itemize}
\item matplotlib core: zlib, zlib-devel, libpng, libpng-devel,
freetype, freetype-devel, freetype-utils
\item gtk backend: gtk2-devel, gtk+-devel, pygtk2, glib-devel,
pygtk2-devel, gnome-libs-devel, pygtk2-libglade
\item tk backend: tcl, tk, tkinter
\item wx, wxagg backend. The wxpython rpms.
\end{itemize}
\subsubsection{Debian and Ubuntu}
\label{sec:debian}
Vittorio Palmisano <\url{redclay@email.it}> maintails the debian
packages at \url{http://mentors.debian.net}. He provides the
following instructions
\begin{itemize}
\item add these lines to your /etc/apt/sources.list:
\begin{verbatim}
deb http://anakonda.altervista.org/debian packages/
deb-src http://anakonda.altervista.org/debian sources/
\end{verbatim}
\item then run
\begin{verbatim}
> apt-get update
> apt-get install python-matplotlib python-matplotlib-doc
\end{verbatim}
\end{itemize}
Alternatively, Andrew Straw maintains an Apt Repository of
scientific Python packages:
\begin{itemize}
\item add these lines to your /etc/apt/sources.list:
\begin{verbatim}
deb http://debs.astraw.com/ dapper/
deb-src http://debs.astraw.com/ dapper/
\end{verbatim}
\end{itemize}
\subsubsection{fink}
\label{sec:fink}
fink users should use Jeffrey Whitaker's matplotlib fink package,
which includes support for the GTK, Tk, and WX GUI toolkits (see \url{http://fink.sourceforge.net/pdb/package.php/matplotlib-py23} or
\url{http://fink.sourceforge.net/pdb/package.php/matplotlib-py24}, or
\url{http://fink.sourceforge.net/pdb/package.php/matplotlib-py25}).
\subsection{Compiling matplotlib}
\label{sec:compilng}
You will need to have recent versions of freetype (>= 2.1.7), libpng
and zlib installed on your system. If you are using a package
manager, also make sure the devel versions of these packages are also
installed (eg freetype-devel).
If you want to use a GUI backend, you will need either Tkinter, pygtk,
PyQt, PyQt4 or wxpython installed on your system, from src or from a
package manager, including the devel packages. You can choose which
backends to enable by setting the flags in setup.py, but the 'auto' flags
will work in most cases, as matplotlib tries to find a GUI and build
the backend accordingly. If you know you don't want a particular backend
or extension, you can set that flag to \val{False}.
Most users will want to keep the setup.py default \code{BUILD\_AGG = 1}.
Exceptions to this are if you know you don't need a GUI (eg a web server)
or you only want to produce vector graphics like postscript, svg or pdf.
If you have installed prerequisites to nonstandard places and need to
inform matplotlib where they are, edit setupext.py an add the base
dirs to the 'basedir' dictionary entry for your sys.platform. Eg, if
the header to some required library is in
\fname{/some/path/include/somheader.h}, put \fname{/some/path} in the
basedir list for your platform.
Note that if you install matplotlib anywhere other than the default
location, you will need to set the \code{MATPLOTLIBDATA} environment
variable to point to the install base dir. Eg, if you install
matplotlib with \code{python setup.py build --prefix=/home/jdhunter}
then set \code{MATPLOTLIBDATA} to \fname{/home/jdhunter/share/matplotlib}.
\subsubsection{OS X}
\label{sec:osx}
All of the backends run on OS~X. fink users consult the fink discussion
in section \ref{sec:fink}. Another option is
\url{http://www.stecf.org/macosxscisoft} which packages many scientific
packages for python on OS~X, including matplotlib, although it is
designed for astronomical analysis.
If you want to compile matplotlib yourself on OS~X, make sure you read the
compiling instructions above. You will need to install freetype2,
libpng and zlib via fink or from src. You will also need the base
libraries for a given backend. Eg, if you want to run TkAgg, you will
need a python with Tkinter; if you want to use WxAgg, install
wxpython. See Section~\ref{sec:intro_backends} for a more comprehensive
discussion of the various backend requirements. Edit \fname{setup.py}
to configure the backends you want to build as described above.
Note when running a GUI backend in OS~X, you should launch your
programs with pythonw rather than python, or you may get
nonresponsive GUIs.
\subsection{Trial Run}
To test your matplotlib installation, run IPython in pylab mode, which
includes special support for interactive use of matplotlib. Linux and Mac
users, run the following in a shell:
\begin{verbatim}
$ ipython -pylab
\end{verbatim}
Windows users can edit the ipython launch icon properties to include
the \code{-pylab} flag.
IPython's pylab mode automatically imports from matplotlib, and prepares
the session for interactive plotting. At the command prompt
(\code{In [1]:}), run the following:
\begin{lstlisting}
plot([1,2,3])
\end{lstlisting}
A window should appear, which looks like figure \ref{fig:simple_plot_tkagg}.
(If you get errors instead of a plot window, you probably were missing one
of the packages required by matplotlib during installation.) Now that we
have demonstrated how easy it can be to get started, perhaps it is now safe
to explore the various options associated with installing and configuring
matplotlib.
\fig{3in}{figures/simple_plot_tkagg}{A simple plot shown in the TkAgg
graphical user interface. Navigation controls shown below the
figure provide an easy way to pan and zoom around your figures, and
a save dialog allows you to save your figure after you have set the
pan and zoom.}{fig:simple_plot_tkagg}
\section{Backends}
\label{sec:intro_backends}
The matplotlib backends are responsible for taking the figure
representation and transferring this to a display device, either a
hardcopy image (\fname{*.jpg}, \fname{*.png}, \fname{*.ps},
\fname{*.svg}, etc) or a GUI window that you can interact with. There
are many GUIs for python: pygtk, wxpython, Tkinter, PyQT, pyfltk, and
more, and matplotlib supports most of them.
In choosing your backend, the following considerations are important:
\begin{itemize}
\item What kind of output do you require? Any matplotlib installation
can generate PS and SVG. For other hardcopy formats, different
backends have different capabilities. Agg can only generate png but
produces the highest quality output (antialiased, alpha). The
native GTK and WX backends support many more image formats (JPG,
TIFF, \dots) but can only be used in GUI mode and produce lower
quality images. The GUI hybrid backends (WXAgg, GTKAgg, Tkagg,
FLTKAgg, QtAgg, Qt4Agg) have the same limitations and capabilities
as Agg.
\item Do you want to produce plots interactively from the python
shell? Because most GUIs have a mainloop, they become unresponsive
to input outside of their mainloop once they are launched. Thus you
often need to use a custom shell to work interactively with a GUI
application from the shell (pycrust for wx, PyShell for gtk). A
notable exception is Tkinter, which can be controlled from a
standard python shell or ipython. Fernando Perez, the author of
ipython, has written a pylab mode for ipython that lets you use WX,
GTK, Qt, Qt4 or Tk interactively from the python shell. If you want
to work interactively with matplotlib, this is the recommended
approach.
\item What platform do you work most on? Do you want to embed
matplotlib in an application that you distribute across platforms?
Do you need a GUI interface? Each of the python GUIs work on all
major platforms, but some are easier than others to install. Each
have different advantages: GTK is natural for linux and has
excellent looking widgets but is a tough install on OS~X. Tkinter
is deployed with most python installations but has primitive looking
widgets. wxpython has native widgets but can be difficult to
install. \textit{Windows users note: the enthought edition of
python from \url{http://www.enthought.com/python} comes with Tkinter
and wxpython included}. Now that Qt-4 has been released under the
GPL for windows, the Qt backend is a new alternative with excellent
looking widgets.
\item What features do you need? Some of the matplotlib features
including alpha blending, antialiasing, images and mathtext are not
ported to all backends. Agg and the *Agg hybrids support all
matplotlib features (agg is a core matplotlib backend). postscript,
native gtk and native wx do not support alpha or antialiasing. svg
supports everything except mathtext (which will hopefully be
supported soon).
\item Do you need dynamic images such as animation? The GUI backends
vary in their ability to support rapid updating of the image
canvas. GTKAgg is currently the fastest backend for animation,
with FLTKAgg a close second.
\end{itemize}
Once you have decided on which backends you want to use, make sure
you have installed the required GUI toolkits (and devel versions
if you are using a package manager). Then install matplotlib and
edit your \fname{matplotlibrc} files to reflect these choices as
described in section \ref{sec:matplotlibrc}.
\section{Integrated development environments}
\label{sec:ides}
If you work primarily in an integrated development environment such as
idle, pycrust, SciTE, Pythonwin, you will probably want to set your
default backend to be compatible with the GUI your IDE uses. See
Table~\ref{tab:ides} for a summary of the various python IDEs and
their matplotlib compatibility.\footnote{If you have experience with
these or other IDEs and matplotlib backends to help me finish this
table, please contact me or the matplotlib-devel mailing list.}
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|l|}\hline
IDE & GUI & Backends and Options\\\hline
idle & Tkinter & Works best with TkAgg if idle is launched with -n\\
pycrust & WX & Works best with WX/WXAgg\\
Scintilla and SciTE & GTK & Should work with GTK/GTKAgg backends but untested\\
Eric3, Eric4 & Qt, Qt4 & works with QtAgg, Qt4Agg\\
pythonwin & MFC & Unknown\\\hline
\end{tabular}
\caption{\label{tab:ides}python IDEs and matplotlib compatibility.
}
\end{table}
\section{Interactive}
\label{sec:interactive}
The recommended way to use matplotlib interactively from a shell is
with IPython. IPython has a \code{-pylab} mode that detects your
matplotlibrc file and makes the right settings to run matplotlib
with your GUI of choice in interactive mode using threading. Ipython's
pylab mode is compatible with the Tk, GTK, WX and Qt GUI toolkits.
GTK users will need to make sure that they have compiled GTK with
threading for this to work. Using ipython in pylab mode is
basically a nobrainer because it knows enough about matplotlib
internals to make all the right settings for you internally.
\begin{lstlisting}
peds-pc311:~> ipython -pylab
Python 2.3.3 (#2, Apr 13 2004, 17:41:29)
Type "copyright", "credits" or "license" for more information.
IPython 0.6.5 -- An enhanced Interactive Python.
? -> Introduction to IPython's features.
%magic -> Information about IPython's 'magic' % functions.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
Welcome to pylab, a matplotlib-based Python environment.
help(matplotlib) -> generic matplotlib information.
help(matlab) -> matlab-compatible commands from matplotlib.
help(plotting) -> plotting commands.
In[1]: plot( rand(20), rand(20), 'go' )
\end{lstlisting}
Note that you did not need to import any matplotlib names because in
pylab mode ipython will import them for you. ipython turns on
interactive mode for you, and also provides a \code{run} command so
you can run matplotlib scripts from the matplotlib shell and then
interactively update your figure. ipython will turn off interactive
mode during a run command for efficiency, and then restore the
interactive state at the end of the run.
\begin{lstlisting}
>>> cd python/projects/matplotlib/examples/
/home/jdhunter/python/projects/matplotlib/examples
>>> run simple_plot.py
>>> title('a new title', color='r')
\end{lstlisting}
The pylab interface provides 4 commands that are useful for
interactive control. Note again that the interactive setting
primarily controls whether the figure is redrawn with each plotting
command. \func{isinteractive} returns the interactive setting,
\func{ion} turns interactive on, \func{ioff} turns it off, and
\func{draw} forces a redraw of the entire figure. Thus when working
with a big figure in which drawing is expensive, you may want to turn
matplotlib's interactive setting off temporarily to avoid the
performance hit
\begin{lstlisting}
>>> run mybigfatfigure.py
>>> ioff() # turn updates off
>>> title('now how much would you pay?')
>>> xticklabels(fontsize=20, color='green')
>>> draw() # force a draw
>>> savefig('alldone', dpi=300)
>>> close()
>>> ion() # turn updates back on
>>> plot(rand(20), mfc='g', mec='r', ms=40, mew=4, ls='--', lw=3)
\end{lstlisting}
If you are not using \code{ipython -pylab}, then by default,
matplotlib defers drawing until the end of the script because drawing
can be an expensive operation. Often you don't want to update the
plot every time a single property is changed, only once after all the
properties have changed. But in interactive mode, eg from the
standard python shell, you usually do want to update the plot with
every command, eg, after changing the xlabel or the marker style of a
line. To do this, you need to set \rc{interactive : True} in your
configuration file; see Section~\ref{sec:matplotlibrc}.
There are many python shells out there: the standard python shell,
ipython, PyShell, pysh, pycrust. Some of these are GUI dependent
(PyShell/pycrust) and some are not (ipython, pysh). As discussed in
backends Section~\ref{sec:ides}, not all shells are compatible
with all matplotlib backends because of GUI mainloop issues. With a
non-GUI python shell such as the standard python shell or
pysh, the TkAgg backend is the best choice for interactive use. Just
set \rc{backend : TkAgg} and \rc{interactive : True} in your
\fname{matplotlibrc} file and fire up python. Then
\begin{lstlisting}
# using matplotlib interactively from the python shell
>>> from pylab import *
>>> plot([1,2,3])
>>> xlabel('hi mom')
\end{lstlisting}
\noindent should work out of the box. Note, in batch mode, ie when making
figures from scripts, interactive mode can be slow since it redraws
the figure with each command. So you may want to think carefully
before making this the default behavior.
\section{Numerix}
\label{sec:numerix}
Numeric is the original python module for efficiently processing arrays of
numeric data. While highly optimized for performance and very stable,
some limitations in the design made it inefficient for very large
arrays, and developers decided it was better to start with a new array
package to solve some of these design problems and numarray was born.
In a sense, the numerical python community split into Numeric and
numarray user groups. Travis Oliphant, one of the maintainers of Numeric,
began work on a third package, based on the Numeric code base, which
incorporated the advances made in numarray, and was called NumPy. NumPy
is intended to be the successor to both Numeric and numarray, and to
reunite the numerical python community. An array interface was developed
in order to allow the three array packages to play well together and to
easy migration to NumPy. Numeric is no longer undergoing active
development, and the numarray release notes suggest users to switch to
Numpy.
Matplotlib requires one of Numeric, numarray, or NumPy to operate. If you
have no experience with any of them, you are strongly advised to install
Numpy and read through some of the documentation before continuing. The
\mpldoc{matplotlib.numerix} module, written by Todd Miller, allows you to
choose between Numeric, numarray and NumPy at the prompt or in a config
file. Thus when you do
\begin{lstlisting}
# import matplotlib and all the numerix functions
from pylab import *
\end{lstlisting}
\noindent you'll not only get all the matplotlib pylab interface
commands, but most of the Numeric, numarray or NumPy package as well
(depending on your numerix setting). All of the array creation and
manipulation functions are imported, such as \func{array},
\func{arange}, \func{take}, \func{where}, etc. The other modules,
such as mlab, fft and linear\_algebra, are available under the numarray
package structure. To make your matplotlib scripts as portable as
possible with respect to your choice of array packages, it is advised
not to explicitly import Numeric, numarray or NumPy. Rather, you should use
matplotlib.numerix where possible, either by using the functions
imported by \mpldoc{pylab}, or by explicitly importing the numerix
module, as in
\begin{lstlisting}
# create a numerix namespace
import matplotlib.numerix as n
x = n.arange(100)
y = n.take(x, range(10,20))
\end{lstlisting}
For the remainder of this manual, the term \textit{numerix} is used to
mean either the Numeric, numarray or NumPy package.
\subsection{Choosing Numeric, numarray, or NumPy}
To select Numeric, numarray, or NumPy from the prompt, run your matplotlib
script with
\begin{verbatim}
> python myscript.py --numarray # use numarray
> python myscript.py --Numeric # use Numeric
\end{verbatim}
\noindent Typically, however, users will choose one or the other and
make this setting in their rc file using either \rc{numerix : Numeric},
\rc{numerix : numarray}, or \rc{numerix : numpy}; see Section~\ref{sec:matplotlibrc}.
Since the array packages all play well together, we expect that in the near
future, matplotlib will depend on NumPy alone.
\section{Customization using \fname{matplotlibrc}}
\label{sec:matplotlibrc}
Almost all of the matplotlib settings and figure properties can be
customized with a plain text file \fname{matplotlibrc}. This file is
installed with the rest of the matplotlib data (fonts, icons, etc)
into a directory determined by distutils. Before compiling
matplotlib, it resides in the same dir as \fname{setup.py} and will be
copied into your install path. Typical locations for this file are
\begin{verbatim}
C:\Python24\Lib\site-packages\matplotlib\mpl-data\matplotlibrc # windows
/usr/lib/python2.4/site-packages/matplotlib/mpl-data/matplotlibrc # linux and friends
\end{verbatim}
\noindent By default, the installer will overwrite the existing file in
the install path, so if you want to preserve your changes, please move it to
the .matplotlib directory in your HOME directory (and set the HOME
environment variable if necessary).
In the rc file, you can set your backend (Section~\ref{sec:intro_backends}),
your numerix setting (Section~\ref{sec:numerix}), whether you'll be
working interactively (Section~\ref{sec:interactive}) and default
values for most of the figure properties.
\subsection{RC file format}
Blank lines, or lines starting with a comment symbol, are ignored,
as are trailing comments. Other lines must have the format
\begin{lstlisting}
key : val # optional comment
\end{lstlisting}
\noindent where \rc{key} is some property like \rc{backend},
\rc{lines.linewidth}, or \rc{figure.figsize} and \rc{val} is the value
of that property. Example entries for these properties are
\begin{lstlisting}
# this is a comment and is ignored
backend : GTKAgg # the default backend
lines.linewidth : 0.5 # line width in points
figure.figsize : 8, 6 # figure size in inches
\end{lstlisting}
\noindent A complete sample rc file is shown in Appendix~\ref{cha:rc}.
The matplotlib rc values are read into a dictionary \code{rcParams} which
contains the key/value pairs. You can changes these values within a
script by importing this dictionary. For example, to require that a
given script uses numarray, you could do
\begin{lstlisting}
from matplotlib import rcParams
rcParams['numerix'] = 'numarray'
from pylab import *
\end{lstlisting}
\noindent Additionally, the commands \mpldoc{matplotlib.rc} and
\mpldoc{matplotlib.rcdefaults} can be used to dynamically customize
the defaults during a script execution (discussed below).
\subsection{Which rc file is used?}
matplotlib will search for an rc file in the following locations
\begin{itemize}
\item The current directory - this allows you to have a project
specific configuration that differs from your default configuration
\item Your HOME dir. On linux and other UNIX operating systems, this
environment variable is set by default. Windows users can set in
the My Computer properties
\item PATH/matplotlibrc where PATH is the return value of
\code{matplotlib.get\_data\_path()}. This function looks where
distutils would have installed the file - if it doesn't find it
there, it checks for the environment variable MATPLOTLIBDATA and
uses that if found. The latter should be set if you are installing
matplotlib to a nonstandard location. Eg, if you install matplotlib
with \code{python setup.py build --prefix=/home/jdhunter} then set
matplotlib data to \fname{/home/jdhunter/share/matplotlib.}
\item After all that, if it cannot find your rc file, it will issue a
warning and use defaults. This is not recommended!
\end{itemize}
\subsection{Getting feedback from matplotlib}
matplotlib uses a verbose setting, defined in the matplotlibrc file
to determine how much information to report.
\begin{verbatim}
verbose.level : error # one of silent, error, helpful, debug, debug-annoying
verbose.fileo : sys.stdout # a log filename, sys.stdout or sys.stderr
verbose.erro : sys.stderr # a log filename, sys.stdout or sys.stderr
\end{verbatim}
\noindent These settings control how much information matplotlib gives you at
runtime and where it goes. The verbosity levels are: \rc{silent,
error, helpful, debug, debug-annoying}. At the \rc{error} level,
you will only get error messages. Any level is inclusive of all the
levels below it. Ie, if your setting is \rc{helpful}, you'll also get
all the \rc{error} messages. If you setting is \rc{debug}, you'll get
all the \rc{error} and \rc{helpful} messages. It is not recommended
to make your setting \rc{silent} because you will not even get
\rc{error} messages. When submitting problems to the mailing-list,
please set verbose to \rc{helpful} or \rc{debug} and paste the output
into your report.
The \rc{verbose.fileo} setting gives the destination for any calls to
the verbose report function. The \rc{verbose.erro} setting gives the
destination for any calls to verbose error reporting function. These
objects can a filename or a full path to a filename, \rc{sys.stderr},
or \rc{sys.stdout}. You can override the rc default verbosity from
the command line by giving the flags {\tt--verbose-LEVEL} where {\tt
LEVEL} is one of the legal levels, eg {\tt --verbose-error} {\tt
--verbose-helpful}.
You can access the verbose instance in your code
\code{from matplotlib import verbose}.
\chapter{The pylab interface}
\label{cha:matlab_interface}
Although matplotlib has a full object oriented API (see
Chapter~\ref{cha:api}), the primary way people create plots is via the
pylab interface, which can be imported with
\begin{lstlisting}
from pylab import *
\end{lstlisting}
\noindent This import command brings in all of the matplotlib code
needed to produce plots, the extra \matlab\ compatible, non-plotting
functions found in \mpldoc{matplotlib.mlab} and all of the
matplotlib.numerix code needed to create and manipulate arrays. When
you import \mpldoc{pylab}, you will get all of NumPy (or Numeric or
numarray depending on your \rc{numerix} setting).
matplotlib is organized around figures and axes. The figure contains
an arbitrary number of axes, which can be placed anywhere in the
figure you want, including over other axes. You can directly create
and manage your own figures and axes, but if you don't, matplotlib
will try and do the right thing by automatically creating default
figures and axes for you.
There are two ways of working in the pylab interface: interactively or
in script mode. When working interactively, you want every plotting
command to update the figure. Under the hood, this means that the
canvas is redrawn after every command that affects the figure. When
working in script mode, this is inefficient. In this case, you only
want the figure to be drawn once, either to the GUI window or saved to
a file. To handle these two cases, matplotlib has an \rc{interactive}
setting in \fname{matplotlibrc}. When \rc{interactive : True}, the
figure will be redrawn with each command. When \rc{interactive :
False}, the figure will be drawn only when there is a call to
\func{show} or \func{savefig}. In the examples that follow, I'll
assume you have set \rc{interactive : True} in your
\fname{matplotlibrc} file and are working from an interactive python
shell using a compatible backend. Please make sure you have read and
understood Sections~\ref{sec:intro_backends}, \ref{sec:ides},
\ref{sec:interactive} and \ref{sec:matplotlibrc}, before trying these
examples.
\section{Simple plots}
\label{sec:simple_plot}
Just about the simplest plot you can create is
\begin{lstlisting}
>>> from pylab import *
>>> plot([1,2,3])
\end{lstlisting}
\noindent I have set my backend to \rc{backend : TkAgg}, which causes
the plot in Figure~\ref{fig:simple_plot_tkagg} to appear, with
navigation controls for interactive panning and zooming.
I can continue to decorate the plot with labels and titles
\begin{lstlisting}
>>> xlabel('time (s)')
>>> ylabel('volts')
>>> title('A really simple plot')
>>> grid(True)
\end{lstlisting}
\noindent and the updated figure is shown in Figure~\ref{fig:simple_plot_tkagg_labeled}.
\fig{3in}{figures/simple_plot_tkagg_labeled}{A simple plot decorated
with some text labels and an axes grid}{fig:simple_plot_tkagg_labeled}
At this point we're getting a little bored plotting \code{[1,2,3]}.
matplotlib is designed around plotting numerix arrays, and can handle
large arrays efficiently. To create a regularly sampled 1\,Hz sine
wave use the arange and sin methods methods provided by numerix which
produces the plot shown in Figure~\ref{fig:simple_plot_tkagg_sine}.
\begin{lstlisting}
>>> t = arange(0.0, 3.0, 0.05) # in matlab t = [0.0: 0.05: 3.0];
>>> s = sin(2*pi*t)
>>> plot(t,s)
\end{lstlisting}
\fig{3in}{figures/simple_plot_tkagg_sine}{A sine wave added to the
simple plot. This may not be what we wanted. Because the
\func{hold} state was on, the two plots were
superimposed.}{fig:simple_plot_tkagg_sine}
\noindent Note that the two plots are superimposed. matplotlib (and
\matlab) have a \func{hold} state. When hold is on, subsequent
plotting commands are superimposed over previous commands. When hold
is off, the plot is cleared with every plotting command. This is
controlled by the \func{hold} command, which can be called like
\code{hold(True)} or \code{hold(False)}. The default setting is in
\fname{matplotlibrc} as \rc{axes.hold : True}, which you can change
according to your preferences. To clear the previous plot and reissue
the plot command for just the sine wave, you can use \func{cla} to
clear the current axes and \func{clf} to clear the current figure, or
simply turn the hold state off.
\begin{lstlisting}
>>> hold(False)
>>> plot(t, s)
\end{lstlisting}
\section{More on plot}
\label{sec:plot}
\subsection{Multiple lines}
\label{sec:plot_multiple_lines}
\func{plot} is a versatile command, and will create an arbitrary
number of lines with different line styles and markers. This example
plots a sine wave and a damped exponential using the default line styles
\begin{lstlisting}
>>> clf() # clear the figure
>>> t = arange(0.0, 5.0, 0.05)
>>> s1 = sin(2*pi*t)
>>> s2 = s1 * exp(-t)
>>> plot(t, s1, t, s2)
\end{lstlisting}
\noindent If you plot multiple lines in a single plot command, the
line color will cycle through a list of predefined colors. The
default line color and line style are determined by the rc parameters
\rc{lines.style} and \rc{lines.color}. You can include an optional
third string argument to each line in the plot command, which
specifies any of the line style, marker style and line color. To plot
the above using a green dashed line with circle markers, and a red
dotted line with circle markers, as shown in
Figure~\ref{fig:plot_styles},
\begin{lstlisting}
>>> clf()
>>> plot(t, s1, 'g--o', t, s2, 'r:s')
>>> legend(('sine wave', 'damped exponential'))
\end{lstlisting}
\fig{3in}{figures/plot_styles}{All line plots take an optional third
string argument, which is composed of (optionally) a line color (eg,
'r', 'g', 'k'), a line style (eg, '-', '--', ':') and a line marker
('o', 's', 'd'). The sine wave line (green dashed line with circle
markers) is created with 'g--o'. The \func{legend} command will
automatically create a legend for all the lines in the plot.
}{fig:plot_styles}
\noindent The color part of the format string applies only to the
facecolor of 2D plot markers like circles, triangles, and squares.
The edgecolor of these markers will be determined by the default rc
parameter \rc{lines.markeredgecolor} and can be defined for individual
lines using the methods discussed below.
\subsection{Controlling line properties}
\label{sec:plot_line_props}
In the last section, we showed how to choose the default line
properties using plot format strings. For finer grained control, you
can set any of the attributes of a \mpldoc{matplotlib.lines.Line2D}
instance. There are three ways to do this: using keyword arguments,
calling the line methods directly, or using the \func{set} command.
The line properties are shown in Table~\ref{tab:line_props}.
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{Property} & \val{Value}\\\hline
\carg{alpha} & The alpha transparency on 0-1 scale\\
\carg{antialiased} & \val{True} or \val{False} - use antialised rendering\\
\carg{color} & A matplotlib color arg\\
\carg{data\_clipping} & Whether to use numeric to clip data\\
\carg{label} & A string optionally used for legend\\
\carg{linestyle} & One of \code{-- : -. -} \\
\carg{linewidth} & A float, the line width in points\\
\carg{marker} & One of \code{$+$ , o . s v x $>$ $<$, etc }\\
\carg{markeredgewidth} & The line width around the marker symbol\\
\carg{markeredgecolor} & The edge color if a marker is used\\
\carg{markerfacecolor} & The face color if a marker is used\\
\carg{markersize} & The size of the marker in points\\\hline
\end{tabular}
\caption{\label{tab:line_props}Line properties; see
\mpldoc{pylab.plot} for more marker
styles}
\end{table}
\subsubsection{Using keyword arguments to control line properties}
\label{sec:plot_kwargs}
You can set any of the line properties listed in
Table~\ref{tab:line_props} using keyword arguments to the plot
command. The following command plots large green diamonds with a red
border
\begin{lstlisting}
>>> plot(t, s1, markersize=15, marker='d', \
... markerfacecolor='g', markeredgecolor='r')
\end{lstlisting}
\subsubsection{Using \func{set} to control line properties}
\label{sec:plot_set_line_props}
You can set any of the line properties listed in
Table~\ref{tab:line_props} using the \func{set} command. Set operates
on the return value of the plot command (a list of lines), so you need
to save the lines. You can use an arbitrary number of key/value pairs
\begin{lstlisting}
>>> lines = plot(t, s1)
>>> set(lines, markersize=15, marker='d', \
... markerfacecolor='g', markeredgecolor='r')
\end{lstlisting}
\noindent \func{set} can either operate on a single instance or a
sequence of instances (in the example code above, \code{lines} is a
length one sequence of lines). Under the hood, if you pass a keyword
arg named \carg{something}, \func{set} looks for a method of the
object called \func{set\_something} and will call it with the value you
pass. If \func{set\_something} does not exist, then an exception will
be raised.
\subsubsection{Using \mpldoc{matplotlib.lines.Line2D} methods}
\label{sec:plot_set_line_methods}
You can also call Line2D methods directly. The return value of plot
is a sequence of \mpldoc{matplotlib.lines.Line2D} instances. Note in
the example below, I use tuple unpacking with the ``,'' to extract the first element
of the sequence as \carg{line}: \code{line, = plot(t, s1)}
\begin{lstlisting}
>>> line, = plot(t, s1)
>>> line.set_markersize(15)
>>> line.set_marker('d')
>>> line.set_markerfacecolor('g')
>>> line.set_markeredgecolor('r')
\end{lstlisting}
\noindent Note, however, that we haven't issued any
\mpldoc{pylab} commands after the initial \func{plot}
command so the figure will not be redrawn even though interactive mode
is set. To trigger a redraw, you can simply resize the figure window
a little or call the \func{draw} method. The fruits of your labors
are shown in Figure~\ref{fig:big_diamonds}.
\begin{lstlisting}
>>> draw()
\end{lstlisting}
\fig{3in}{figures/big_diamonds}{Large green diamonds with red borders,
created with three different recipes.}{fig:big_diamonds}
\subsubsection{Abbreviated method names}
\label{sec:line_abbrevs}
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{Abbreviation} & \val{Fullname}\\\hline
aa & antialiased\\
c & color\\
ls & linestyle\\
lw & linewidth\\
mec & markeredgecolor\\
mew & markeredgewidth\\
mfc & markerfacecolor\\
ms & markersize\\\hline
\end{tabular}
\caption{\label{tab:line_abbrevs}Abbreviated names for line
properties. You can use any of the line customization methods
above with abbreviated names.}
\end{table}
When working from an interactive python shell, typing
'markerfacecolor' can be a pain -- too many keystrokes. The
\mpldoc{matplotlib.lines.Line2D} class provides a number of
abbreviated method names, listed in Table~\ref{tab:line_abbrevs}.
\noindent Thus you can, for example, call
\begin{lstlisting}
# no antialiasing, thick green markeredge lines
>>> plot(range(10), 'ro', aa=False, mew=2, mec='g')
\end{lstlisting}
\section{Color arguments}
\label{sec:colors}
matplotlib is fairly tolerant of a number of formats for passing color
information. As discussed above, you can use and of the single
character color strings listed in Table~\ref{tab:color_strings}.
Additionally, anywhere a color character string is accepted, you can
also use a grayscale, hex, RGB color argument, or any legal hml color
name, ebg ``red'' or ``darkslategray''.
\fig{4in}{figures/color_demo}{Lots of different ways to specify colors
generated from Listing~\ref{lst:color_demo}-- not necessarily
recommended for aesthetic quality!}{fig:color_demo}
\lstinputlisting[linerange=1-12,caption={Wild and wonderful ways to specify colors;
see Figure~\ref{fig:color_demo}},
label=lst:color_demo]{code/color_demo.py}
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
b & blue\\
g & green\\
r & red\\
c & cyan\\
m & magenta\\
y & yellow\\
k & black\\
w & white\\
0.75 & a grayscale intensity (any float in [0,1]\\
\#2F4F4F & an RGB hex color string, eg, this example is dark slate
gray\\
(0.18, 0.31, 0.31) & an RGB tuple; this is also dark slate gray\\
red & any legal html color name\\\hline
\end{tabular}
\caption{\label{tab:color_strings}Color format strings, which can be
used to set the line or text properties, eg the line, the marker
edgecolor or marker facecolor. }
\end{table}
\section{Loading and saving data}
\label{sec:loading_data}
\mpldoc{pylab} provides support for loading and saving
ASCII arrays or vectors with the \func{load} and \func{save} command.
\mpldoc{matplotlib.numerix} provides support for loading and saving
binary arrays with the \func{fromstring} and \func{tostring} methods.
\subsection{Loading and saving ASCII data}
\label{sec:ascii_data}
Suppose you have an ASCII file of measured times and voltages like so
\begin{verbatim}
0.0000 0.4911
0.0500 0.5012
0.1000 0.7236
0.1500 1.1756
... and so on
\end{verbatim}
\noindent You can load that data into an array \code{X} with the \func{load}
command. The shape of X is numSamples rows by 2 columns, with the
first column containing the time points and the second column
containing the measured voltages. You can use numerix array indexing
to extract the two columns into the 1D arrays \code{t} and \code{s}
\begin{lstlisting}
X = load('../data/ascii_data.dat')
t = X[:,0] # the first column
s = X[:,1] # the second row
plot(t, s, 'o')
\end{lstlisting}
Likewise, you can save array or vector data in an ASCII file
with the \func{save} command. The following script was used to create
the sample data above
\lstinputlisting{code/gen_ascii_data.py}
\subsection{Loading and saving binary data}
\label{sec:binary_data}
ASCII is bloated and slow for working with large arrays, and so binary
data should be used if performance is a consideration. To save the
array \code{X} in binary form, use the numerix \func{tostring} method
\begin{lstlisting}
# open the file for writing binary and write the binary string
file('../data/binary_data.dat', 'wb').write(X.tostring())
\end{lstlisting}
\noindent This data can later be loaded into a numerix array using
\func{fromstring}. This method takes two arguments, a string and a
data type (note that numarray users can use \func{fromfile} which is
more efficient for importing data directly from a file).
\lstinputlisting{code/load_binary_data.py}
\noindent Note that although Numerix and numarray use different
typecode arguments (Numeric uses strings whereas numarray uses type
objects), the matplotlib.numerix compatibility layer provides symbols
which will work with either \rc{numerix} rc setting.
\subsection{Processing several data files}
\label{sec:multiple_files}
Since python is a programming language \textit{par excellence}, it is
easy to process data in batch. When I started the gradual transition
from a full time \matlab\ user to a full time python user, I began
processing my data in python and saving the results to data files for
plotting in \matlab. When that became too cumbersome, I decided to
write matplotlib so I could have all the functionality I needed in one
environment. Here is a brief example showing how to iterate over
several data files, named \fname{basename001.dat, basename002.dat,
basename003.dat, ... basename100.dat} and plot all of the traces to
the same axes. I'll assume for this example that each file is a 1D
ASCII array, which I can load with the \func{load} command.
\begin{lstlisting}
hold(True) # set the hold state to be on
for i in range(1,101): #start at 1, end at 100
fname = 'basename%03d.dat'%i # %03d pads the integers with zeros
x = load(fname)
plot(x)
\end{lstlisting}
\section{axes and figures}
\label{sec:axes_and_figures}
All the examples thus far used \textit{implicit} figure and axes
creation. You can use the functions \func{figure}, \func{subplot},
and \func{axes} to explicitly control this process. Let's take a look
at what happens under the hood when you issue the commands
\begin{lstlisting}
>>> from pylab import *
>>> plot([1,2,3])
\end{lstlisting}
When plot is called, the pylab interface makes a call to \func{gca()}
(``get current axes'') to get a reference to the current axes.
\func{gca} in turn, makes a call to \func{gcf} to get a reference to
the current figure. \func{gcf}, finding that no figure has been
created, creates the default figure \code{figure()} and returns it.
\func{gca} will then return the current axes of that figure if it
exists, or create the default axes \code{subplot(111)} if it does
not. Thus the code above is equivalent to
\begin{lstlisting}
>>> from pylab import *
>>> figure()
>>> subplot(111)
>>> plot([1,2,3])
\end{lstlisting}
\subsection{\func{figure}}
\label{sec:figure}
You can create and manage an arbitrary number of figures using the
\func{figure} command. The standard way to create a figure is to
number them from $1 \dots N$. A call to \code{figure(1)} creates
figure 1 if it does not exist, makes figure 1 active (\func{gcf} will
return a reference to it), and returns the
\mpldoc{matplotlib.figure.Figure} instance. The syntax of the
\func{figure} command is
\begin{lstlisting}
def figure(num=1,
figsize = None, # defaults to rc figure.figsize
dpi = None, # defaults to rc figure.dpi
facecolor = None, # defaults to rc figure.facecolor
edgecolor = None, # defaults to rc figure.edgecolor
frameon = True, # whether to draw the figure frame
):
\end{lstlisting}
\carg{figsize} gives the figure size in inches and is width by
height. Eg, to create a figure 12 inches wide and 2 inches high, you
can call \code{figure(figsize=(12,2))}. \carg{dpi} gives the dots per
inch of your display device. Increasing this number effectively
creates a higher resolution figure. \carg{facecolor} and
\carg{edgecolor} determine the face and edge color of the figure
rectangular background. This is what gives the figure a gray
background in the GUI figures such as
Figure~\ref{fig:simple_plot_tkagg}. You can turn this background
completely off by setting \code{frameon=False}. The default for
saving figures is to have a white face and edge color, and all of
these properties can be customized using the rc parameters
\rc{figure.*} and \rc{savefig.*}.
In typical usage, you will only provide the figure number, and let
your rc parameters govern the other figure attributes
\begin{lstlisting}
>>> figure(1)
>>> plot([1,2,3])
>>> figure(2)
>>> plot([4,5,6])
>>> title('big numbers') # figure 2 title
>>> figure(1)
>>> title('small numbers') # figure 1 title
\end{lstlisting}
You can close a figure simply by clicking on the close ``x'' in the
GUI window, or by issuing the \func{close} command. \func{close} can
be used to close the current figure, a figure referenced by number, a
given figure instance, or all figures
\begin{itemize}
\item \code{close()} by itself closes the current figure
\item \code{close(num)} closes figure number \val{num}
\item \code{close(fig)} where \val{fig} is a figure instance closes
that figure
\item \code{close('all')} closes all the figure windows
\end{itemize}
\noindent If you close a figure directly, eg \code{close(2)} the
previous current figure is restored to the current figure. \func{clf}
is used to clear the current figure without closing it.
If you save the return value of the figure command, you can call any
of the methods provided by \mpldoc{matplotlib.figure.Figure}, for
example, you can set the figure facecolor
\begin{lstlisting}
>>> fig = figure(1)
>>> fig.set_facecolor('g')
\end{lstlisting}
or use \func{set} for the same purpose
\begin{lstlisting}
>>> set(fig, facecolor='g')
\end{lstlisting}
\subsection{\func{subplot}}
\label{sec:subplot}
\func{axes} and \func{subplot} are both used to create axes in a
figure. \func{subplot} is used more commonly, and creates axes
assuming a regular grid of axes \carg{numRows} by \carg{numCols}.
For example, to create two rows and one column of axes, you would use
\code{subplot(211)} to create the upper axes and \code{subplot(212)}
to create the lower axes. The last digit counts across the rows.
\fig{4in}{figures/subplot_demo}{Multiple rows of axes created with the
subplot command, as shown in
Listing~\ref{lst:subplot_demo}}{fig:subplot_demo}
\lstinputlisting[linerange=1-22,caption={Generating multiple axes with subplot; see Figure~\ref{fig:subplot_demo}}, label=lst:subplot_demo]{code/subplot_demo.py}
\noindent Likewise, to create two columns and one row of axes, you would use
\code{subplot(121)} to create the left axes and \code{subplot(122)} to
create the right axes. If the total number of axes exceeds single
digits, use comma separated arguments to subplot. For example, the
lower right panel of a 3 x 4 grid of axes is created with
\code{subplot(3,4,12)}. matplotlib uses \matlab\ style indexing in
creating figures and axes, so \code{subplot(3,4,1)} is the first
subplot, not \code{subplot(3,4,0)}.
The subplot command returns a \mpldoc{matplotlib.axes.Subplot}
instance, which is derived from \mpldoc{matplotlib.axes.Axes}. Thus
you can call and Axes or Subplot method on it. When creating multiple
subplots with the same axes, for example the same time axes, sometimes
it helps to turn off the x tick labeling for all but the lowest plot.
Here is some example code
\begin{lstlisting}
subplot(211)
plot([1,2,3], [1,2,3])
set(gca(), xticklabels=[])
subplot(212)
plot([1,2,3], [1,4,9])
\end{lstlisting}
Likewise, with multiple columns and shared y axes, you may want turn
off the ytick labels for all but the first row. The subplot command
returns a \mpldoc{matplotlib.axes.Subplot} instance, which is derived
from \mpldoc{matplotlib.axes.Axes}. Thus you can call and Axes or
Subplot method on it. Subplot defines some helper methods
(\func{is\_first\_row}, \func{is\_first\_col}, \func{is\_last\_row},
\func{is\_last\_col}, to help you conditionally set subplot properties,
eg
\begin{lstlisting}
cnt = 0
for i in range(numRows):
for j in range(numCols):
cnt += 1
ax = subplot(numRows, numCols, cnt)
plot(blah, blah)
if ax.is_last_row() : xlabel('time (s)')
if ax.is_first_col() : ylabel('volts')
\end{lstlisting}
Here is some example code to create multiple figures and axes, using
the \func{figure} and \func{subplot} command to control the current
figure and axes.
\lstinputlisting{code/multiple_figures.py}
\subsection{\func{axes}}
\label{sec:axes}
When you need a finer grained control over axes placement than
afforded by \func{subplot}, use the \func{axes} command. The
\func{axes} command in initialized with a rectangle \code{[left,
bottom, width, height]} in relative figure coordinates. \code{left,
bottom = (0, 0)} is the bottom left of the of the figure canvas, and
a \code{width}/\code{height} of 1 spans the figure width/height. This to create an
axes that entirely fills the figure canvas, you would do \code{axes([0,
1, 0, 1])}. This may not be a good idea, because it leaves no room
for text labels. \code{axes([0.25, 0.25, 0.5, 0.5])} creates an axes
offset by one quarter of the figure width and height on all sides.
There are several ways to use the \func{axes} command; in all cases, a
\mpldoc{matplotlib.axes.Axes} instance is returned
\begin{itemize}
\item \code{axes()} by itself creates a default full
\code{subplot(111)} window axis
\item \code{axes(rect, axisbg='w')} where \code{rect=[left, bottom,
width, height]} in normalized (0,1) units. \carg{axisbg} is the
background color for the axis, default white.
\item \code{axes(ax)} where \carg{ax} is an axes instance makes
\carg{ax} current.
\end{itemize}
\noindent \func{gca} returns the current axes instance and \func{cla}
clears the current axes. You can use the \func{axes} command lay the
axes exactly where you want them, including to overlaying one axes on
top of another, as in this example
\fig{4in}{figures/axes_demo}{Using the \func{axes} command to create
inset axes over another axes; see Listing~\ref{lst:axes_demo}}{fig:axes_demo}
\lstinputlisting[linerange=1-27,caption={Custom axes;
see Figure~\ref{fig:axes_demo}}, label=lst:axes_demo]{code/axes_demo.py}
\section{Text}
\label{sec:text}
matplotlib has excellent text support, including newline separated
text with arbitrary rotations and mathematical expressions. freetype2
support produces very nice, antialiased fonts, that look good even at
small raster sizes. It includes its own font\_manager, thanks to Paul
Barrett, which implements a cross platform, W3C compliant font finding
algorithm. You have total control over every text property (font
size, font weight, text location and color, etc) with sensible
defaults set in the rc file. And significantly for those interested
in mathematical or scientific figures, matplotlib implements a large
number of \TeX\ math symbols and commands, to support mathematical
expressions anywhere in your figure. To get the most out of text in
matplotlib, you should use a backend that supports freetype2 and
mathtext, notably all the *Agg backends (see
Section~\ref{sec:intro_backends}), or the postscript backend, which
embeds the freetype fonts directly into the PS/EPS output file.
\subsection{Basic text commands}
\label{sec:basic_text}
The following commands are used to create text in the pylab
interface
\begin{itemize}
\item \func{xlabel(s)} - add a label \carg{s} to the x axis
\item \func{ylabel(s)} - add a label \carg{s} to the y axis
\item \func{title(s)} - add a title \carg{s} to the axes
\item \func{text(x, y, s)} - add text \carg{s} to the axes at
\carg{x}, \carg{y} in data coords
\item \func{figtext(x, y, s)} - add text to the figure at \carg{x},
\carg{y} in relative 0-1 figure coords
\end{itemize}
\subsection{Text properties}
\label{sec:text_props}
The text properties are listed in Table~\ref{tab:text_props}. As with
lines, there are three ways to set text properties: using keyword
arguments to a text command, calling \func{set} on a text instance or
a sequence of text instances, or calling an instance method on a text
instance. These three are illustrated below
\begin{lstlisting}
# keyword args
>>> xlabel('time (s)', color='r', size=16)
>>> title('Fun with text', horizontalalignment='left')
# use set
>>> locs, labels = xticks()
>>> set(labels, color=g', rotation=45)
# instance methods
>>> l = ylabel('volts')
>>> l.set_weight('bold')
\end{lstlisting}
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{Property} & Value\\\hline
\carg{alpha} & The alpha transparency on 0-1 scale\\
\carg{color} & A matplotlib color arg\\
\carg{family} & set the font family, eg 'sans-serif', 'cursive', 'fantasy'\\
\carg{fontangle} & the font slant, one of 'normal', 'italic', 'oblique'\\
\carg{horizontalalignment} & 'left', 'right' or 'center'\\
\carg{multialignment} & 'left', 'right' or 'center'
only for multiline strings\\
\carg{name} & the font name, eg, 'Sans', 'Courier', 'Helvetica'\\
\carg{position} & the x,y location\\
\carg{variant} & the font variant, eg 'normal', 'small-caps'\\
\carg{rotation} & the angle in degrees for rotated text\\
\carg{size} & the fontsize in points, eg, 8, 10, 12\\
\carg{style} & the font style, one of 'normal', 'italic',
'oblique'\\
\carg{text} & set the text string itself\\
\carg{verticalalignment} & 'top', 'bottom' or 'center'\\
\carg{weight} & the font weight, eg 'normal', 'bold', 'heavy',
'light'\\\hline
\end{tabular}
\caption{\label{tab:text_props}Properties of
\mpldoc{matplotlib.text.Text}}
\end{table}
\noindent See the example
\url{http://matplotlib.sourceforge.net/examples/fonts_demo_kw.py}
which makes extensive use of font properties for more information.
See also Chapter~\ref{cha:font_finding} for more discussion of the
font finder algorithm and the meaning of these properties.
\subsection{Text layout}
\label{sec:text_layout}
You can layout text with the alignment arguments
\carg{horizontalalignment}, \carg{verticalalignment}, and
\carg{multialignment}. \carg{horizontalalignment} controls whether
the x positional argument for the text indicates the left, center or
right side of the text bounding box. \carg{verticalalignment} controls
whether the y positional argument for the text indicates the bottom,
center or top side of the text bounding box. \carg{multialignment},
for newline separated strings only, controls whether the different
lines are left, center or right justified. Here is an example which
uses the \func{text} command to show the various alignment
possibilities. The use of \code{transform=ax.transAxes} throughout
the code indicates that the coordinates are given relative to the axes
bounding box, with 0,0 being the lower left of the axes and 1,1 the
upper right.
\fig{6in}{figures/alignment_demo}{Aligning text with
\carg{horizontalalignment}, \carg{verticalalignment}, and
\carg{multialignment} options to the \func{text} command; see
Listing~\ref{lst:align_text}}{fig:align_text}
\lstinputlisting[linerange=1-73,caption={Aligning text; see Figure~\ref{fig:align_text}},
label=lst:align_text]{code/alignment_demo.py}
\subsection{mathtext}
\label{sec:mathtext}
matplotlib supports \TeX\ mathematical expressions anywhere a text
string can be used, as long as the string is delimited by ``\$'' on
both sides, as in $\mathtt{r'\$5\backslash lambda\$'}$; embedded %FIXME
mathtext strings, such as in $\mathtt{r'The\ answer\ is\ \$5\backslash
lambda\$'}$ are not currently supported. A large set of the \TeX\
symbols from the computer modern fonts are provided. Subscripting and
superscripting are supported, as well as the over/under style of
subscripting with $\mathtt{\backslash sum}$, $\mathtt{\backslash int}$
etc.
Note that matplotlib does not use or require that \TeX\ be installed on
your system, as it does not use it. Rather, it uses the parsing
module \fname{pyparsing} to parse the \TeX\ expression, and does the
layout manually in the \mpldoc{matplotlib.mathtext} module using the
font information provided by \mpldoc{matplotlib.ft2font}.
\noindent The spacing elements $\backslash/$ and $\mathtt{\backslash
hspace\{num\}}$ are provided. $\backslash /$ inserts a small space,
and $\mathtt{\backslash hspace\{num\}}$ inserts a fraction of the
current fontsize. Eg, if \code{num=0.5} and the fontsize is 12.0,
$\mathtt{\backslash hspace\{0.5\}}$ inserts 6 points of space.
The following accents are provided: $\mathtt{\backslash hat}$,
$\mathtt{\backslash breve}$, $\mathtt{\backslash grave}$,
$\mathtt{\backslash bar}$, $\mathtt{\backslash acute}$,
$\mathtt{\backslash tilde}$, $\mathtt{\backslash vec}$,
$\mathtt{\backslash dot}$, $\mathtt{\backslash ddot}$. All of them
have the same syntax, eg to make an $\bar{o}$ you do
$\mathtt{\backslash bar\{o\}}$ or to make an $\ddot{o}$ you do
$\mathtt{\backslash ddot\{o\}}$. The shortcuts are also provided, eg:
\begin{verbatim}
\"o \'e \`e \~n \.x \^y
\end{verbatim}
\subsection{Annotations}
\label{sec:annotations}
The uses of the basic \func{text} command above place text at an
arbitrary position on the Axes. A common use case of text is to
\emph{annotate} some feature of the plot, and the \func{Axes.annotate}
method (pylab method \func{annotate}) provides helper functionality to
make annotations easy. In an annotation, there are two points to
consider: the location being annotated represented by the argument
\carg{xy} and the location of the text \carg{xytext}. Both of these
arguments are \code{(x,y)} tuples. Optionally, you can specify the
coordinate system of xy and xytext with one of the following strings
for \carg{xycoords} and \carg{textcoords} (default is 'data')
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
argument & coordinate system\\
'figure points' & points from the lower left corner of the figure\\
'figure pixels' & pixels from the lower left corner of the figure\\
'figure fraction' & 0,0 is lower left of figure and 1,1 is upper, right\\
'axes points' & points from lower left corner of axes\\
'axes pixels' & pixels from lower left corner of axes\\
'axes fraction' & 0,1 is lower left of axes and 1,1 is upper right\\
'data' & use the axes data coordinate system\\\hline
\end{tabular}
\caption{\label{tab:annotation}Coordinate systems for the text point \carg{xy} and annotation text point \carg{xytext} are supplied by optional keyword arguments \carg{xycoords} and \carg{textcoords} .
}
\end{table}
For physical coordinate systems (points or pixels) the origin is the
(bottom, left) of the figure or axes. If the value is negative,
however, the origin is from the (right, top) of the figure or axes,
analogous to negative indexing of sequences.
Optionally, you can specify arrow properties which draws and arrow
from the text to the annotated point by giving a dictionary of arrow
properties in the optional keyword argument \carg{arrowprops}.
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{arrowprops} key & description\\
width & the width of the arrow in points\\
frac & the fraction of the arrow length occupied by the head\\
headwidth & the width of the base of the arrow head in points\\
shrink & move the tip and base some percent away from the annotated point and text\\
**kwargs & any key for \code{matplotlib.patches.polygon} (eg facecolor)\\\hline
\end{tabular}
\caption{\label{tab:arrowprops}keys controlling the arrow properties in the \carg{arrowprops} dictionary.
}
\end{table}
\fig{4in}{figures/annotation_demo}{Sample annotation output generated from Listing~\ref{lst:annotation_demo} }{fig:annotation_demo}
\lstinputlisting[linerange=1-27,caption={Annotations with different coordinate systems for the annotated point and text
see Figure~\ref{fig:annotation_demo}},
label=lst:annotation_demo]{code/annotation_demo.py}
\subsubsection{Licensing}
\label{sec:mathtext_license}
The computer modern fonts this package uses are part of the BaKoMa
fonts, which are (in my understanding) free for noncommercial use.
For commercial use, please consult the licenses in fonts/ttf and the
author Basil K. Malyshev - see also
\url{http://www.mozilla.org/projects/mathml/fonts/encoding/license-bakoma.txt}
and the file BaKoMa-CM.Fonts in the matplotlib fonts dir.
Note that all the code in this module is distributed under the
matplotlib license, and a truly free implementation of mathtext for
either freetype or ps would simply require deriving another concrete
implementation from the Fonts class defined in this module which used
free fonts.
\subsubsection{Using mathtext}
Any text element can use math text. You need to use raw strings
(preceed the quotes with an \code{r}), and surround the string text
with dollar signs, as in \TeX.
\begin{lstlisting}
# plain text
title('alpha > beta')
# math text
title(r'$\alpha > \beta$')
\end{lstlisting}
\noindent To make subscripts and superscripts use the underscore and caret
symbols, as in
\begin{lstlisting}
title(r'$\alpha_i > \beta^i$')
\end{lstlisting}
You can also use a large number of the \TeX\ symbols, as in
$\mathtt{\backslash infty}$, $\mathtt{\backslash leftarrow}$,
$\mathtt{\backslash sum}$, $\mathtt{\backslash int}$; see
Appendix~\ref{cha:math_symbols} for a complete list. The over/under
subscript/superscript style is also supported. To write the sum of
$x_i$ from 0 to $\infty$ ($\sum_{i=0}^\infty x_i$), you could do
\begin{lstlisting}
text(1, -0.6, r'$\sum_{i=0}^\infty x_i$')
\end{lstlisting}
The default font is \textit{italics} for mathematical symbols. To
change fonts, eg, to write 'sin' in a \textrm{roman font}, enclose the
text in a font command, as in
\begin{lstlisting}
text(1,2, r's(t) = $\cal{A}\rm{sin}(2 \omega t)$')
\end{lstlisting}
\noindent Here '$s$' and '$t$' are variable in italics font (default),
'$\mathrm{sin}$' is in roman font, and the amplitude '$\mathcal{A}$'
is in caligraphy font. The fonts $\mathtt{\backslash cal}$,
$\mathtt{\backslash rm}$, $\mathtt{\backslash it}$ and
$\mathtt{\backslash tt}$ are allowed.
Fairly complex \TeX\ expressions render correctly; you can compare the
expression
\begin{verbatim}
s = r'$\cal{R}\prod_{i=\alpha}^\infty a_i\rm{sin}(2 \pi f x_i)$'
\end{verbatim}
\noindent rendered by \TeX\ below and by matplotlib in
Figure~\ref{fig:mathtext_demo}.
\begin{equation}
\mathcal{R}\prod_{i=\alpha}^\infty a_i\mathrm{sin}(2 \pi f x_i)
\end{equation}
\fig{4in}{figures/mathtext_demo}{Incorpating \TeX\ expressions into
your figure; see Listing~\ref{lst:mathtext_demo}}{fig:mathtext_demo}
\lstinputlisting[linerange=1-17,caption={Using mathtext; see
Figure~\ref{fig:mathtext_demo}},
label=lst:mathtext_demo]{code/mathtext_demo.py}
\subsubsection{usetex}
If you have \LaTeX, ghostscript, and dvipng installed on your computer,
matplotlib can use \LaTeX to perform all of the text layout in your
figures. To enable this option, set \code{text.usetex : True} in your
rc settings. For more information and examples, see
\url{http://www.scipy.org/Cookbook/Matplotlib/UsingTex} .
\section{Images}
\label{sec:images}
matplotlib provides support for working with raw image data in numerix
arrays. Currently, there is no support for loading image data from
image files such as PNG, TIFF or JPEG, though this is on the TODO
list. If you need to load data from existing image files, one good
solution is to use The Python Imaging Library to load the data and
convert this to a numerix array - see Recipe~\ref{cbook:image_files}.
The following examples will assume you have your image data loaded
into a numerix array, either luminance (MxN), RGB (MxNx3) or RGBA
(MxNx4).
\subsection{Axes images}
\label{sec:image_axes}
An axes image is created with \code{im = imshow(X)} where
\carg{X} is a numerix array an \carg{im} is a
\mpldoc{matplotlib.image.AxesImage} instance. The image is rescaled to fit
into the current axes box. Here is some example code to display an
image
\lstinputlisting[linerange=1-4]{code/simple_imshow.py}
\noindent \func{imshow} a command in the \mpldoc{pylab}
interface. This is a thin wrapper of the
\mpldoc{matplotlib.Axes.imshow} method, which can be called from any
Axes instance, eg \code{ax.imshow(X)}.
There are two parameters that determine how the image is resampled
into the axes bounding box: \carg{interpolation} and \carg{aspect}.
The following \carg{interpolation} schemes are available:
\val{bicubic, bilinear, blackman100, blackman256, blackman64, nearest,
sinc144, sinc256, sinc64, spline16, and spline36}. The default
interpolation method is given by the value of \rc{image.interpolation}
in your \fname{matplotlibrc} file. \carg{aspect} can be either
\val{equal}, \val{auto}, or some number, which will constrain the
aspect ratio of the image. The default aspect setting is given by
the value of the rc parameter \rc{image.aspect}.
The full syntax of the \func{imshow} command is
\begin{lstlisting}
imshow(X, # the numerix array
cmap = None, # the matplotlib.colors.Colormap instance
norm = None, # the normalization instance
aspect=None, # the aspect setting
interpolation=None, # the interpolation method
alpha=1.0, # the alpha transparency value
vmin = None, # the min for image scaling
vmax = None, # the max for image scaling
origin=None): # the image origin
\end{lstlisting}
When \val{None}, these parameters will assume a default value, in
many cases determined by the rc setting. The meaning of \carg{cmap,
norm, vmin, vmax, and origin} will be explained in sections below.
The following shows a simple command which creates an image using
bilinear interpolation, shown in Figure~\ref{fig:image_demo}.
\fig{4in}{figures/image_demo}{Simple axes image; code in Listing~\ref{lst:image_demo}}{fig:image_demo}
\lstinputlisting[linerange=1-13,caption={Axes images; see Figure~\ref{fig:image_demo}},
label=lst:image_demo]{code/image_demo.py}
You can create an arbitrary number of axes images inside a single
axes, and these will be composed via alpha blending. However, if you
want to blend several images, you must make sure that the
\func{hold} state is \val{True} and that the alpha of the
layered images is less than 1.0; if alpha=1.0 then the image on top
will totally obscure the images below. Because the image blending is
done using antigrain (regardless of your backend choice), you can
blend images even on backends which don't support alpha (eg,
postscript). This is because the alpha blending is done in the
frontend and the blended image is transferred directly to the backend
as an RGB pixel array. See Recipe~\ref{cbook:layer_images} for an example of
how to layer images.
\subsection{Figure images}
\label{sec:image_figure}
Often times you want to be able to look at your raw image data
directly, without interpolation. This is the function of figure
images, which do a pixel-by-pixel transfer of your image data to the
figure canvas \footnote{If you want a resampled image to occupy the
full space of the figure canvas, you can achieve this by specifying
a custom axes that fills the figure canvas \code{axes([0, 1, 0,
1])} and using \func{imshow}.}. Figure images are drawn first,
and thus can become the background of other matplotlib drawing
commands.
In the pylab interface, figure images are created with the
\func{figimage} command, which unlike \func{imshow}, does not
accept an \carg{interpolation} or \carg{aspect} keyword argument
because no image resampling is used. If the pixel extent of the
figure image extends beyond the figure canvas, the image will simply
be truncated. The basic syntax is \code{figimage(X, xo=0, yo=0)}
where X is luminance (MxN), RGB (MxNx3) or RGBA (MxNx4) numerix array
and \carg{xo}, \carg{yo} are pixel offsets from the origin (see
Section~\ref{sec:image_origin}). You can use \func{figimage} to create a
figure image that fills the entire canvas with no x or y offsets, or
you can make multiple calls to \func{figimage} with different x and
y offsets to create a mosaic of images, as shown in
Recipe~\ref{cbook:figure_mosaic}.
The full syntax of the \func{figimage} command is
\begin{lstlisting}
figimage(X, # the numerix array
xo=0, # the x offset
yo=0, # the y offset
alpha=1.0, # the alpha transparency
norm=None, # the matplotlib.colors.normalization instance
cmap=None, # the matplotlib.colors.Colormap instance
vmin=None, # the min for image scaling
vmax=None, # the max for image scaling
origin=None) # the image origin
\end{lstlisting}
The \carg{cmap, norm, vmin, vmax} and \carg{origin} arguments are
explained in the sections below.
\mpldoc{pylab.figimage} is a thin wrapper of
\mpldoc{matplotlib.figure.figimage} and you can generate figure images
directly with the pythonic API using \code{fig.figimage(X)} where
fig is a Figure instance.
\subsection{Scaling and color mapping}
\label{sec:image_to_rgba}
In addition to supporting raw image RGB and RGBA formats, matplotlib
will scale and map luminance data for MxN float (luminance) arrays.
The conversion from luminance data to RGBA occurs in two steps:
scaling and color mapping.
\textit{Scaling} is the process of normalizing an MxN floating point
array to the 0,1 interval, by mapping \carg{vmin} to 0.0 and
\carg{vmax} to 1.0, where \carg{vmin} and \carg{vmax} are user defined
parameters. If either are \val{None}, the min and max of the image
data will be used, respectively. Scaling is handled by a
\mpldoc{matplotlib.colors.normalization} instance, which defaults to
\code{normalization(vmin=None, vmax=None)} - ie, the default is to
scale the image so that the minimum of the luminance array is zero and
the maximum of the luminance array is one.
Typically, you will not create a normalization instance yourself, but
may set \carg{vmin} or \carg{vmax} in the keyword arguments of the
image creation function. In this case, a normalization instance is
created for you, and your vmin, vmax settings are applied. If you do
supply a normalization instance for the \carg{norm} argument,
\carg{vmin} and \carg{vmax} will be ignored. See
Table~\ref{tab:image_norms} for some examples of image normalization
commands and their interpretation.
\begin{table}[htbp]
\centering
\begin{tabular}[t]{ll}
command& interpretation\\
\prompt{imshow(X)} &
$X \leq \mathrm{min}(X) \rightarrow 0 $ and $X \geq \mathrm{max}(X) \rightarrow 1$\\
\prompt{imshow(X, vmax=10)} &
$X \leq \mathrm{min}(X) \rightarrow 0 $ and $X \geq 10 \rightarrow 1$\\
\prompt{imshow(X, vmin=0, vmax=10)} &
$X \leq 0 \rightarrow 0 $ and $X \geq 10 \rightarrow 1$\\
\prompt{anorm=normalize(2,8)} & \\
\prompt{imshow(X, norm=anorm)} &
$X \leq 2 \rightarrow 0 $ and $X \geq 8 \rightarrow 1$\\
\end{tabular}
\caption{\label{tab:image_norms}Example image normalization commands
and their interpretation}
\end{table}
Once the luminance data are normalized, they color mapper transforms
the normalized data to RGBA using a
\mpldoc{matplotlib.colors.Colormap} instance. Common colormaps are
defined in \mpldoc{matplotlib.cm}, including \code{cm.jet} and
\code{cm.gray}. If the cmap argument to an image command is
\val{None}, the default is given by he rc parameter \rc{image.cmap}.
The keyword arguments \carg{cmap, norm, vmin, vmax} control color
mapping and scaling in the image construction commands. Once the
images have been created, several commands exist to interactively
control the color map of the current image. Like the current figure
(\func{gcf}) and the current axes (\func{gca}), matplotlib keeps
track of the current image (\func{gci}) to determine which image to
apply the commands which affect image properties. To interactively
set the image normalization limits, use \code{clim(vmin=None,
vmax=None)}, where \carg{vmin} and \carg{vmax} have the same meaning
as above. To interactively change the colormap, use \func{jet} or
\func{gray} (More colormaps and colormap commands are planned)..
These latter commands not only change the colormap of the current
image, they also set the default for future images.
For quantitative plotting of pseduocolor images, use the
\func{colorbar} function to provide a colorbar associated with the
image, Here is an example interactive session controlling image
scaling and color mapping with a colorbar
\begin{lstlisting}
>>> imshow(X) # plot the luminance image X
>>> clim(-1,2) # scale the image
>>> jet() # use colormap jet
>>> colorbar() # add a colorbar to the current axes
>>> gray() # use grayscale; image and colorbar are updated
\end{lstlisting}
The image scaling and color mapping are handled by the mixin base
class \mpldoc{matplotlib.colors.ScalarMappable}.
\subsection{Image origin}
\label{sec:image_origin}
Depending on your data, it may be more natural to plot your data with
the image origin up (\code{X[0,0]} is upper left) or down
(\code{X[0,0]} is lower left). matplotlib supports these two modes
with the \carg{origin} parameter, which can be supplied as an optional
keyword argument to the image commands \func{imshow} and
\func{figimage} with the default set by the rc parameter
\rc{image.origin}. To plot an image with the origin in the upper
left, pass \code{origin='upper'} and with the image in the lower left,
pass \code{origin='lower'}, as shown in Figure~\ref{fig:image_origin}.
\fig{4in}{figures/image_origin}{Controlling the image origin with the
\carg{origin} keyword argument to \func{imshow} and
\func{figimage}; see Listing~\ref{lst:image_origin}.}{fig:image_origin}
\lstinputlisting[linerange=1-11,caption={Setting the image origin;
see Figure~\ref{fig:image_origin}},label=lst:image_origin]{code/image_origin.py}
\section{Bar charts, histograms and errorbar plots}
\label{sec:barcharts}
Use the \func{bar} function to create simple bar plots. The simplest
form of this function is simply \code{bar(x,y)} which creates bars
with their left edge at \val{x} and height \val{y}. There are a
number of options to support more sophisticated bar plots, including
stacked bar plots and bar plots with errorbars. The signature of the
bar method is
\begin{lstlisting}
def bar(left, height, width=0.8, bottom=0,
color='b', yerr=None, xerr=None,
ecolor='k', capsize=3
):
\end{lstlisting}
\subsection{Broken bar charts}
\label{sec:broken_bar}
matplotlib provides a collection
\code{matplotlib.collections.BrokenBarHCollection}, and a wrapper
function \code{broken\_barh} to facilitate plotting a series of
\code{(xmin, xwidth)} ranges with horizontal bars. This functionality
is typically used in plotting temporal data, when you want to visually
represent the windows of time where a certain feature is available,
etc... The signature of the class and the wrapper function are
\begin{lstlisting}
def broken_barh(self, xranges, yrange, **kwargs):
"""
A collection of horizontal bars spanning yrange with a sequence of
xranges
xranges : sequence of (xmin, xwidth)
yrange : (ymin, ywidth)
kwargs are PatchCollection properties
"""
\end{lstlisting}
The collection properties are controlled with standard
\code{matplotlib.collections.PatchColllection} kwargs
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{Property} & \val{Value}\\\hline
\carg{edgecolors} & a single edge colors or a sequence\\
\carg{facecolors} & a single facecolor or a sequence\\
\carg{linewidths} & a single linewidth or a sequence \\\hline
\end{tabular}
\caption{\label{tab:events}The broken bar collection properties}
\end{table}
Any of these arguments can be a single object, like
\code{facecolors='blue'} in which case all bars will be homogeneous on
that property, or a sequence, eg \code{facecolors=('blue', 'red',
'green')} which will capply different colors to the bars.
\fig{4in}{figures/broken_barh}{This graph simulates data in which a
race was interrupted and the bars show the time periods when the
race was on and when it was interrupted; code is in
Listing~\ref{lst:broken_barh}. The annotation command used here is
discussed in Section~\ref{sec:annotations} }{fig:broken_barh}
\lstinputlisting[linerange=1-18,caption={Use the broken\_barh to make
horizontal broken bar plots, eg to represent intervals where
something is turned on or off; see Figure~\ref{fig:broken_barh}. },
label=lst:broken_barh]{code/broken_barh.py}
\section{Polar charts}
\label{sec:polar_charts}
matplotlib has a \code{PolarAxes} class and a \func{polar} function in
the pylab interface. Not every matplotlib polar function is supported
on polar axes, but most are: you can do polar line plots, bar charts,
scatter plots, area fills, text and legends.
To create a \code{PolarSubplot}, pass the \code{polar=True} keyword
argument to the axes or subplot creation fuinction you are using, eg
to create a
\begin{lstlisting}
subplot(211, polar=True)
\end{lstlisting}
or
\begin{lstlisting}
axes([left, bottom, width, height], polar=True)
\end{lstlisting}
The view limits (eg \code{xlim} and \code{ylim}) apply to the lower
left and upper right of the rectangular box that surrounds to polar
axes. Eg if you have
\begin{lstlisting}
r = arange(0,1,0.01)
theta = 2*pi*r
\end{lstlisting}
the lower left corner is $5/4\pi, \sqrt{2}$ and the
upper right corner is $1/4\pi, \sqrt{2}$.
To customize the radial and angular gridding, ticking and formatting,
a few helper methods of the polar axes (with corresponding pylab
interface wrappers) are provided.
To customize the radial grids, the PolarAxes has a method
\func{set\_rgrids} (the pylab method is simply \code{rgrids}).
\begin{lstlisting}
def set_rgrids(self, radii, labels=None, angle=22.5, rpad=0.05, **kwargs):
\end{lstlisting}
This method will set the radial locations and labels of the radial
grids. The \code{labels} will appear at radial distances \code{radii}
at the specified \code{angle}. \code{labels}, if not \code{None}, is
a \code{len(radii)} list of strings of the labels to use at each
angle. If \code{labels} is \code{None}, the radial tick formatter
\code{ax.rformatter} will be used. \code{rpad} is a fraction of the
max of \code{radii} which will pad each of the radial labels in the
radial direction. You can use the additional keyword arguments in
\code{kwargs} to pass in \code{matplotlib.text.Text} properties to
customize the text labels.
Similarly, to set and format the angular gridlines and labels, use the
\code{set\_thetagrids} function. See the class documentation -- the
signature is similar to the rgrids method discussed above.
The \code{PolarAxes} will clip all objects to the circular polygon
which comprises the Axes bounding polygon, and you can use the
\code{set\_rmax} method to set the maximum radius and data that will be
visible.
\fig{4in}{figures/polar_demo}{A polar line chart; code is in
Listing~\ref{lst:polar_demo}. }{fig:polar_demo}
\lstinputlisting[linerange=1-19,caption={A simple polar line plot; see
Figure~\ref{fig:polar_demo}. The matplotlib source distribution has
addition examples \fname{polar\_scattter.py}, \fname{polar\_bar.py} and
\fname{polar\_legend.py} which show how to make additional polar plot
types.}, label=lst:polar_demo]{code/polar_demo.py}
\section{Pseudocolor and scatter plots}
\label{sec:pcolor_scatter}
\section{Spectral analysis}
\label{sec:spectral}
matplotlib provides a number of \matlab\ compatible functions for
computing and plotting spectral analysis results. All of them are
based on Welch's Averaged Periodogram Method \citep{BendatPiersol1986}
using the numerix \code{fft} method for the fast fourier transforms.
The spectral plotting functions are \func{psd} for the power spectral
density, \func{csd} for the cross spectral density, and \func{cohere}
for the coherence (normalized cross spectral density).
\begin{lstlisting}
# signature and defaults for arguments to a typical
# spectral analysis function
def psd(x, NFFT=256, Fs=2, detrend=mlab.detrend_none,
window=mlab.window_hanning, noverlap=0):
\end{lstlisting}
In addition to the time series arguments x/y, these functions take a
number of optional parameters. The averaged periodogram method chops
the time series into \carg{NFFT} length segments which overlap by
\carg{noverlap} samples. The default values are \code{NFFT=256} and
\code{noverlap=0}. Each of the functions will compute the spectral
analysis and then generate a plot window with frequency on the x-axis
- if you want the frequency axis to be properly scaled, you should
provide the sampling frequency \carg{Fs}.
Each of the segments will be detrended and windowed before the fft,
according to the values of \carg{detrend} and \carg{window}. Unlike
\matlab, in which these arguments are strings, in matplotlib they are
functions. Several helper functions are provided in matplotlib.mlab
for detrending and windowing:
\begin{itemize}
\item \func{mlab.detrend\_none} - no detrending
\item \func{mlab.detrend\_mean} - remove the mean of each segment before fft
\item \func{mlab.detrend\_linear} - remove the best fit line of each segment
before fft
\item \func{mlab.window\_none} - no windowing
\item \func{mlab.window\_hanning} - multiply each segment by a Hanning window
\end{itemize}
\noindent An example power spectra calculation is shown in
Listing~\ref{lst:versus_matlab} and the output in
Figure~\ref{fig:psd_py}.
You can create a spectrogram with the \func{specgram} function.
\func{specgram} splits the data into NFFT length segments and plots
the instantaneous power in each segment along the y axis using a
pseudocolor plot, unlike \func{psd} which averages the power across
each segment.
\fig{4in}{figures/specgram_demo}{A spectrogram generated by Listing~\ref{lst:specgram_demo}}{fig:specgram_demo}
\lstinputlisting[linerange=2-26,caption={Instantaneous power spectra with
\func{specgram}; see Figure~\ref{fig:specgram_demo}},
label=lst:specgram_demo]{code/specgram_demo.py}
\section{Axes properties}
\label{sec:axes_props}
\section{Legends and tables}
\label{sec:legends_and_tables}
\section{Navigation}
\label{sec:navigation}
matplotlib comes with two navigation toolbars for the graphical user
interfaces: classic and toolbar2. You can use these to change the
view limits of the axes in the figure. toolbar2 superceeds classic
and was designed to overcome shortcomings of the classic toolbar. The
default toolbar is determined by the \rc{toolbar} parameter in
\fname{matplotlibrc}.
\subsection{Classic toolbar}
\label{sec:toolbar_classic}
You can pan and zoom on the X and Y axis for any combination of the
axes that are plotted. If you have a wheel mouse, you can move
bidirectionally by scrolling the wheel over the controls. For
examples, the wheel mouse can be used to pan left or right by
scrolling over either of the left arrow or right arrow buttons, so you
never have to move the mouse to pan the x-axis left and right. If you
don't have a wheel mouse, buy one!
The left widget that says 'All' on the controls on the bottom of
Figure~\ref{fig:toolbar_classic} is a drop down menu used to select
which axes the controls affect. You can select all, none, single, or
combinations of axes. The first set of 4 controls are used to pan
left, pan right, zoom in and zoom out on the x axes. The second set
are used to pan up, pan down, zoom in and zoom out on the y axes. The
remaining buttons are used to redraw the figure, save (PNG or JPEG)
the figure, or to close the figure window.
\fig{4in}{figures/toolbar_classic}{The classic toolbar, discussed
in Section~\ref{sec:toolbar_classic}}{fig:toolbar_classic}
\subsection{toolbar2}
\label{sec:toolbar_toolbar2}
The toolbar2 buttons (see Figure~\ref{fig:toolbar_toolbar2} behave
very differently from the classic the classic matplotlib toolbar (else
why introduce a new one!) despite the visual similarity of the forward
and back buttons.
The \texttt{Forward} and \texttt{Back} buttons are akin to the web browser
forward and back buttons. They are used to navigate back and forth
between previously defined views. They have no meaning unless you
have already navigated somewhere else using the pan and zoom buttons.
This is analogous to trying to click 'back' on your web browser before
visiting a new page. Nothing happens. \texttt{Home} always takes you to
the first view. For \texttt{Home}, \texttt{Forward} and \texttt{Back}, think web
browser where data views are web pages. Use the \texttt{Pan/Zoom} and
\texttt{Zoom to rectangle} buttons, discussed below, to define new views.
The \texttt{Pan/Zoom} button has two modes: pan and zoom. Click this
toolbar button to activate this mode. Then put your mouse somewhere
over an axes.
\begin{itemize}
\item Mode 1: Press the left mouse button and hold it, dragging it to
a new position. When you release it, the data under the point where
you pressed will be moved to the point where you released. If you
press 'x' or 'y' while panning, the motion will be contrained to the
x or y axis, respectively
\item Mode 2: Press the right mouse button, dragging it to a new
position. The x axis will be zoomed in proportionate to the
rightward movement and zoomed out proportionate to the leftward
movement. Ditto for the yaxis and up/down motions. The point under
your mouse when you begin the zoom should remain in place, allowing
you to zoom to an arbitrary point in the figure. You can use the
modifier keys 'x', 'y' or 'CONTROL' to constrain the zoom to the x
axes, the y axes, or aspect ratio preserve, respectively.
\end{itemize}
The \texttt{Zoom to rectangle} button: Click this toolbar button to
activate this mode. Put your mouse somewhere over and axes and press
the left mouse button. Drag the mouse while holding the button to a
new location and release. The axes view limits will be zoomed to the
rectangle you have defined. There is also an experimental 'zoom out
to rectangle' in this mode with the right button, which will place
your entire axes in the region defined by the zoom out rectangle.
The \texttt{Save} button: click this button to launch a file save
dialog. All the *Agg backends know how to save the following image
types: PNG, PS, EPS, SVG. There is no support currently in Agg for
writing to JPEG, TIFF (the regular wx and gtk backends handle these
types). It is possible to use matplotlib/agg + PIL to convert agg
images to one of these other formats if required. I can provide a
recipe for you. I prefer PNG over JPG and TIFF, which is why I
haven't worked too hard to include these other image formats in agg.
\fig{4in}{figures/toolbar_toolbar2}{The newfangled toolbar2, discussed
in Section~\ref{sec:toolbar_toolbar2}}{fig:toolbar_toolbar2}
\section{Event handling}
\label{sec:events}
When visualizing data, it's often helpful to get some interactive
input from the user. All graphical user interfaces (GUIs) provide
event handling to determine things like key presses, mouse position,
and button clicks. matplotlib supports a number of GUIs, and provides
an interface to the GUI event handling via the \func{mpl\_connect} and
\func{mpl\_disconnect} methods of the pylab interface (API users will
probably want to use their GUIs event handling directly, but do have
the option of using their \mpldoc{FigureCanvas.mpl\_connect} method).
matplotlib uses a callback event handling mechanism. The basic idea
is that you register an event that you want to listen for, and the
figure canvas, will call a user defined function when that event
occurs. For example, if you want to know where the user clicks a
mouse on your figure, you could define a function
\begin{lstlisting}
# this function will be called with every click
def click(event):
print 'you clicked', event.x, event.y
# register this function with the event handler
cid = connect('button_press_event', click)}.
\end{lstlisting}
\noindent Then
whenever the user clicks anywhere on the figure canvas, your function
will be called and passed a
\mpldoc{matplotlib.backend\_bases.MplEvent} instance. The event
instance will have the following attributes defined.
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{Property} & \val{Meaning}\\\hline
\carg{x} & x position - pixels from left of canvas\\
\carg{y} & y position - pixels from bottom of canvas\\
\carg{button} & button pressed None, 1, 2, 3\\
\carg{inaxes} & the Axes instance if mouse is over axes (or None)\\
\carg{xdata} & x coord of mouse in data coords (None if mouse
isn't over axes)\\
\carg{ydata} & y coord of mouse in data coords (None if mouse
isn't over axes)\\
\carg{name} & The string name of the event\\
\carg{canvas} & The FigureCanvas instance the event occured in\\
\carg{key} & The key press if any, eg 'a', 'b', '1'. Also
records 'control and 'shift'\\\hline
\end{tabular}
\caption{\label{tab:events}The event attributes}
\end{table}
\noindent You can connect to the following events: 'button\_press\_event',
'button\_release\_event', 'motion\_notify\_event',
'key\_press\_event', and 'key\_release\_event'.
You can connect multiple event handlers, and later disconnect them if
you want with the disconnect function
\begin{lstlisting}
# register this function with the event handler
def click1(event): pass
def click2(event): pass
cid1 = connect('key_press_event', click1)}.
cid2 = connect('key_press_event', click2)}.
...later on....
disconnect(cid1) # now only click2 is connected
\end{lstlisting}
Here's an example to get the mouse location in data coordinates as the
mouse moves
\lstinputlisting{code/coords_demo.py}
\section{Customizing plot defaults}
\label{sec:rc_command}
\chapter{Font finding and properties}
\label{cha:font_finding}
\mpldoc{matplotlib.fonts.font\_manager} is module for finding,
managing, and using fonts across-platforms. This module provides a
single FontManager that can be shared across backends and platforms.
The findfont() method returns the best TrueType (TTF) font file in the
local or system font path that matches the specified FontProperties.
The FontManager also handles Adobe Font Metrics (AFM) font files for
use by the PostScript backend.
The design is based on the W3C Cascading Style Sheet, Level 1 (CSS1)
font specification (\url{http://www.w3.org/TR/1998/REC-CSS2-19980512}).
Future versions may implement the Level 2 or 2.1 specifications.
The \rc{font.family} property has five values: 'serif' (e.g. Times),
'sans-serif' (e.g. Helvetica), 'cursive' (e.g. Zapf-Chancery),
'fantasy' (e.g. Western), and 'monospace' (e.g. Courier). Each of
these font families has a default list of font names in decreasing
order of priority associated with them. You describe which family you
want by choosing, eg, \code{family='serif'}, and the font manager will
search the font.serif list looking for one of the named fonts on your
system. The lists are user configurable, and reside in your
\fname{matplotlibrc}.
This allows you to choose your family in your matplotlib script and
the font manager will try and find the best font no matter which
platform you run on.
\begin{itemize}
\item The \rc{font.style} property has three values: normal (or
roman), italic or oblique. The oblique style will be used for
italic, if it is not present.
\item The \rc{font.variant} property has two values: normal or
small-caps. For TrueType fonts, which are scalable fonts,
small-caps is equivalent to
using a font size of 'smaller', or about 83% of the current font size.
\item The \rc{font.weight} property has effectively 13 values: normal,
bold, bolder, lighter, 100, 200, 300, ..., 900. Normal is the same
as 400, and bold is 700. bolder and lighter are relative values
with respect to the current weight.
\item The \rc{font.stretch} property has 11 values: ultra-condensed,
extra-condensed, condensed, semi-condensed, normal, semi-expanded,
expanded, extra-expanded, ultra-expanded, wider, and narrower. This
property is not currently implemented.
\item The \rc{font.size} property is the default font size for text,
given in pts. 12pt is the standard value. Special text sizes for
tick labels, axes, labels, title, etc. can be defined relative to
\rc{font.size} using the following values: xx-small, x-small,
small, medium, large, x-large, xx-large, larger, or smaller. Special
text sizes can also be an absolute size, given in pts.
\end{itemize}
Here is an example using the font properties to illustrate the
different fonts
\lstinputlisting{code/fonts_demo_kw.py}
% TODO: fix me for PS
%\fig{6in}{figures/fonts_demo_kw}{The various fonts rendered by the
% script above}{fig:fonts_demo}
\chapter{Collections}
\label{cha:collections}
\chapter{Tick locators and formatters}
\label{cha:tickers}
The \mpldoc{matplotlib.ticker} module contains classes to support
completely configurable tick locating and formatting. Although the
locators know nothing about major or minor ticks, they are used by the
Axis class to support major and minor tick locating and formatting.
Generic tick locators and formatters are provided, as well as domain
specific custom locators an formatters.
\section{Tick locating}
\label{sec:ticklocs}
Choosing tick locations and formats is a difficult and essential part
of making nice looking graphs. The \mpldoc{matplotlib.ticker} module
divides the workload between two bases classes: the locators and the
formatters. Each axis (eg the xaxis and yaxis) has a major and minor
tick locator and a major and minor tick formatter. The default minor
tick locators always return the empty list, ie, there are no minor
ticks. Each of these can be set independently, and it is easy for the
user to create and plug-in a custom tick locator or formatter.
The \mpldoc{matplotlib.ticker.Locator} class is the base class for all
tick locators. The locators handle autoscaling of the view limits
based on the data limits, and choosing the tick locations. The most
generally useful tick locator is \mpldoc{MultipleLocator}. You
initialize this with a base, eg 10, and it picks axis limits and ticks
that are multiples of your base. The class \mpldoc{AutoLocator}
contains a \mpldoc{MultipleLocator} instance, and dynamically updates
it based upon the data and zoom limits. This should provide much more
intelligent automatic tick locations both in figure creation and in
navigation than in prior versions of matplotlib. See
Tables~\ref{tab:locators} and \ref{tab:date_locators} for a summary of
the basic and date tick locators.
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{Class} & \val{Summary}\\\hline
NullLocator & No ticks\\
IndexLocator & locator for index plots (eg where \code{x = range(len(y))}\\
LinearLocator & evenly spaced ticks from min to max\\
LogLocator & logarithmically ticks from min to max\\
MultipleLocator & ticks and range are a multiple of base;
either integer or float \\
AutoLocator & choose a MultipleLocator and dynamically reassign\\\hline
\end{tabular}
\caption{\label{tab:locators}The basic tick locators}
\end{table}
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{Class} & \val{Summary}\\\hline
MinuteLocator & locate minutes \\
HourLocator & locate hours \\
DayLocator & locate specifed days of the month\\
WeekdayLocator & Locate days of the week, eg MO, TU\\
MonthLocator & locate months, eg 7 for july\\
YearLocator & locate years that are multiples of base\\
RRuleLocator & locate using a matplotlib.dates.rrulewrapper.
The rrulewrapper is a simple wrapper around a dateutils.rrule
\url{https://moin.conectiva.com.br/DateUtil} which allow almost
arbitrary date tick specifications. See
\fname{examples/date\_demo\_rrule.py}.
\end{tabular}
\caption{\label{tab:date_locators}The tick locators specialized for
date plots; these reside in the \mpldoc{matplotlib.dates} module}
\end{table}
You can define your own locator by deriving from Locator. You must
override the \code{\_\_call\_\_} method, which returns a sequence of
locations, and you will probably want to override the autoscale method
to set the view limits from the data limits. If you want to override
the default locator, use one of the above or a custom locator and pass
it to the x or y axis instance. The relevant methods are
\begin{lstlisting}
ax.xaxis.set_major_locator( xmajorLocator )
ax.xaxis.set_minor_locator( xminorLocator )
ax.yaxis.set_major_locator( ymajorLocator )
ax.yaxis.set_minor_locator( yminorLocator )
\end{lstlisting}
\noindent The default minor locator is the NullLocator, eg no minor ticks on by
default.
\section{Tick formatting}
Tick formatting is the process of converting the numeric tick location
into a suitable string, and is controlled by classes derived from
\mpldoc{matplotlib.ticker.Formatter}. The formatter operates on a
single tick value (and its tick position) and returns a string to the
axis. The tick formatters are summarized in
Table~\ref{tab:formatters}.
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
\carg{Class} & \val{Summary}\\\hline
NullFormatter & no labels on the ticks\\
FixedFormatter & set the strings manually for the labels\\
FuncFormatter & user defined function sets the labels\\
FormatStrFormatter & use a sprintf format string\\
IndexFormatter & cycle through fixed strings by tick position\\
ScalarFormatter & default formatter for scalars; autopick the fmt string\\
LogFormatter & formatter for log axes\\
DateFormatter & use an strftime string to format the date\\\hline
\end{tabular}
\caption{\label{tab:formatters}The tick formatting classes}
\end{table}
You can derive your own formatter from the Formatter base class by
simply overriding the \_\_call\_\_ method. The formatter class has
access to the axis view and data limits.
To control the major and minor tick label formats, use one of the
following methods::
\begin{lstlisting}
ax.xaxis.set_major_formatter( xmajorFormatter )
ax.xaxis.set_minor_formatter( xminorFormatter )
ax.yaxis.set_major_formatter( ymajorFormatter )
ax.yaxis.set_minor_formatter( yminorFormatter )
\end{lstlisting}
\section{Example 1: major and minor ticks}
In this example, the xaxis has major ticks that are multiples of 20
and minor ticks that are multiples of 5. The ticks are formatted with
an integer format string formatter '\%d'. The minor ticks are
unlabelled (\code{NullFormatter}).
The \code{MultipleLocator} ticker class is used to place ticks on
multiples of some base. The \code{FormatStrFormatter} uses a string format
string (eg'\%d' or '\%1.2f' or '\%1.1f cm' ) to format the tick.
Note that the pylab interface grid command changes the grid settings
of the major ticks of the y and y axis together. If you want to
control the grid of the minor ticks for a given axis, use for example
\code{ax.xaxis.grid(True, which='minor')}. See
Figure~\ref{fig:major_minor_demo}.
\fig{4in}{figures/major_minor_demo}{Creating custom major and minor
tick locators and formatters; see
Listing~\ref{lst:major_minor_demo}}{fig:major_minor_demo}
\lstinputlisting[linerange=1-21,caption={Custom tickers and formatters;
see Figure~\ref{fig:major_minor_demo}},
label=lst:major_minor_demo]{code/major_minor_demo.py}
\section{Example 2: date ticking}
Making nice date/time plots requires custom tick locating and
formatting. matplotlib converts all datetimes to days since
0001-01-01, and uses a floating point number to represent fractions of
days. The functions \func{date2num} and \func{num2date} are used to
convert back and forth between python datetimes and these floating
point numbers.
The example below uses the \mpldoc{matplotlib.finance} module to get
some historical quotes from yahoo's historical quotes server. The
datetime start and end points are specified using a python's datetime
module. Major ticks are on the months (\code{MonthLocator}) and minor
ticks are on Mondays (\code{WeekdayLocator}). Only the major ticks
are labelled, using a strftime format string (\code{DateFormatter}).
Finally since the y axis is a stock price, a string formatter
(\code{FormatStrFormatter}) is used to place dollar signs on the y
tick labels.
\fig{4in}{figures/date_ticker_demo}{Providing custom tick locators and
formatters for financial/date plots; see
Listing~\ref{lst:date_ticker_demo}.}{fig:date_ticker_demo}
\lstinputlisting[linerange=1-48,caption={Custom date tick locators and formatters;
see Figure~\ref{lst:date_ticker_demo}},
label=lst:date_ticker_demo]{code/date_ticker_demo.py}
\chapter{Interactive object picking}
\label{cha:picking}
When interacting with a plot in a user interface window, it is often
helpful to be able to select, or ``pick'' graphical elements with a
mouse click or a lasso select. matplotlib provides a pick interface
to select and inspect objects and their data though a pick event
handler. Everything in the graph, from basic elements like Text,
Line2D, Polygon to complex objects like Figure, Axes and Axis, are
derived from the matplotlib Artist base class, and each artist defines
a \code{pick} method that responds to mouse click events and fires a
\code{pick\_event} when the mouse click is over the artist. When
selected, the code{pick\_event} is fired off and clients who are
registered to get callbacks on \code{pick\_event} will be notified with
a callback with the following signature
\begin{lstlisting}
def onpick(event):
pass
fig.canvas.mpl_connect('pick_event', onpick)
\end{lstlisting}
\code{event} is a \code{matplotlib.backend\_bases.PickEvent} instance
which has attributes
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|}\hline
attribute & Description\\\hline
mouseevent & the MouseEvent that generated the pick\\
artist & the artist picked\\\hline
\end{tabular}
\caption{\label{tab:pickeventattrs}The \code{PickEvent} attributes
}
\end{table}
In addition, certain matplotlib Artists, such as \code{Line2D} may
attach additional type dependent attributes. For example, Line2D
attaches \code{ind} which is a sequeunce of integers giving the
indices into the data of the points which meet the pick criterion
tolerance. These extra attributes are documented in the
\code{Artist.pick} method, eg, from
\code{matplotlib.lines.Line2D.pick}
\begin{lstlisting}
def pick(self, mouseevent):
"""
If mouseevent is over data that satisifies the picker, fire
off a backend_bases.PickEvent with the additional attribute "ind"
which is a sequence of indices into the data that meet the criteria
"""
\end{lstlisting}
In order to enable picking on a given artist, you need to set the
\carg{pickeps} property, which take several forms. At the most basic
level, it is simply a boolean \code{True|False} which will
enable/disable picking for that artist and the artist defines a
default rule for hit testing (eg for Text, if the mouse click occurs
in the rectangular bounding box surrounding the text it will fire off
a \code{pick\_event}. Alternatively, one can specify a scalar value
which is interpreted as a epsilon tolerance distance in printer's
points; Line2D for example will determine the indicies of all the data
points which fall within this epsilon tolerance distance. The list of
valid picker values and types is given in the table below.
\begin{table}[htbp]
\centering
\begin{tabular}[t]{|l|l|l|}\hline
\code{picker} value & description\\\hline
None & picking is disabled for this artist (default)\\
boolean & if True then picking will be enabled and the
artist will fire a pick event if the mouse event is over
the artist\\
float & if \code{picker} is a number it is interpreted as an
epsilon tolerance in points and the the Artist will fire
off an event if it's data is within epsilon of the mouse
event. For some artists like lines and patch collections,
the Artist may provide additional data to the pick event
that is generated, eg the indices of the data within
epsilon of the pick event\\
function & if \code{picker} is callable, it is a user supplied
function which determines whether the artist is hit by the
mouse event. \code{hit, props = picker(artist, mouseevent)}
to determine the hit test. if the mouse event is over the
artist, return \code{hit=True} and \code{props} is a dictionary of properties
you want added to the \code{PickEvent} attributes\\\hline
\end{tabular}
\caption{\label{tab:picker}The valid types and their interpretation for the \carg{picker} Artist property.
}
\end{table}
The example below shows how to enable picking on basic matplotlib
Artists (Line2D, Rectangle and Text). Note that the picker property
must be explicitly set either as a keyword argument to the plotting
function that creates the Artist (eg \code{plot} or \code{bar}) or by
setting the property of the Artist directly (eg
\code{label.set\_picker(True)})
\lstinputlisting[caption={Basic picker event handling},
label=lst:pick_demo1]{code/pick_demo1.py}
You can also define your own custom hit testing function and return
custom data to the callback. This is very useful if you want to
define your own distance metric or to decorate your plot objects with
custom data and return it to the user through the pick infrastructure,
eg to query plot objects for associated data. In the example below we
define the pick distance function to operate in data coordinate space
rather than printer's points, and return additional metadata to the
user, specifically the x and y coordinates of the pick point in data
coordinates
\lstinputlisting[caption={Defining custom hit testing functions},
label=lst:pick_demo2]{code/pick_demo2.py}
\section{Picking with a lasso tool}
matplotlib provides a lasso tool to select a region of the plot, and
some high performance hit testing functions to query whether a point
or group of points is withing the polygon created by the lasso.
The basic lasso widget is defined in \code{matplotlib.widgets} and is
initialized with an Axes instance, an \code{x,y} starting location,
and a callback function. The widget will handle the mouse movement
events and trigger a callback with the vertices of the lasso when the
mouse button is released. A standard use case is to create the lasso
on a button press event with the Axes in which the mouse press
occurred and the x,y locations of the mouse press event.
\begin{lstlisting}
def onpress(self, event):
if self.canvas.widgetlock.locked(): return
if event.inaxes is None: return
self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback)
# acquire a lock on the widget drawing
self.canvas.widgetlock(self.lasso)
\end{lstlisting}
The callback function will get the vertices of the lasso, and can use
the \code{matplotlib.nxutils.points\_inside\_poly} function to test
whether a list of x,y points are inside the lasso region or not.
\begin{lstlisting}
def callback(self, verts):
# self.xys is a sequene of (x,y) data points and verts are
# the x,y vertices of the lasso polygon
ind = nx.nonzero(points_inside_poly(self.xys, verts))
self.canvas.draw_idle()
self.canvas.widgetlock.release(self.lasso)
del self.lasso
\end{lstlisting}
In the example code, we allso manage the widget locking of the canvas
so different widgets will not compete to draw on the canvas at the
same time, eg a rectangular select widget and a lasso widget may both
need to get a lock on the canvas at different times. A complete
example is below
\begin{lstlisting}
from matplotlib.widgets import Lasso
import matplotlib.mlab
from matplotlib.nxutils import points_inside_poly
from matplotlib.colors import colorConverter
from matplotlib.collections import RegularPolyCollection
from pylab import figure, show, nx
class Datum:
colorin = colorConverter.to_rgba('red')
colorout = colorConverter.to_rgba('green')
def __init__(self, x, y, include=False):
self.x = x
self.y = y
if include: self.color = self.colorin
else: self.color = self.colorout
class LassoManager:
def __init__(self, ax, data):
self.axes = ax
self.canvas = ax.figure.canvas
self.data = data
self.Nxy = len(data)
self.facecolors = [d.color for d in data]
self.xys = [(d.x, d.y) for d in data]
self.collection = RegularPolyCollection(
fig.dpi, 6, sizes=(100,),
facecolors=self.facecolors,
offsets = self.xys,
transOffset = ax.transData)
ax.add_collection(self.collection)
self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)
def callback(self, verts):
#ind = matplotlib.mlab._inside_poly_deprecated(self.xys, verts)
ind = nx.nonzero(points_inside_poly(self.xys, verts))
for i in range(self.Nxy):
if i in ind:
self.facecolors[i] = Datum.colorin
else:
self.facecolors[i] = Datum.colorout
self.canvas.draw_idle()
self.canvas.widgetlock.release(self.lasso)
del self.lasso
def onpress(self, event):
if self.canvas.widgetlock.locked(): return
if event.inaxes is None: return
self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback)
# acquire a lock on the widget drawing
self.canvas.widgetlock(self.lasso)
data = [Datum(*xy) for xy in nx.mlab.rand(100, 2)]
fig = figure()
ax = fig.add_subplot(111, xlim=(0,1), ylim=(0,1), autoscale_on=False)
lman = LassoManager(ax, data)
show()
\end{lstlisting}
\chapter{Custom objects and units}
\label{cha:units}
matplotlib provides support for working with custom objects that know
how to convert themselves to numeric-like objects. Suppose you want
to plot a certain type of object (eg a python \code{datetime.date})
and you do not have access to the code to provide an array interface
to it. This may be because the object is coming from a 3rd party or
from some part of your API that you do not have control over. You
could wrap it to put an array interface around it, but then it may not
work properly with other parts of your code, again parts you may not
have control over. To support this, matplotlib allows you to register
object types with conversion interfaces.
As a simple example, matplotlib assumes dates are passed as floating
point days since '0000-00-00'. To work with native python date
objects, we need to provide a conversion interface that converts
\code{datetime.date} objects to the floats matplotlib is expecting.
The basic conversion interface is in \code{matplotlib.units}.
Additionally, we can provide axis info to enable default axis
labeling, tick locating and tick formatting. Here is the basic
conversion interface required to support dates
\begin{lstlisting}[caption={Conversion interface for working with
python dates}, label=lst:datesupport]
import matplotlib
from matplotlib.cbook import iterable, is_numlike
import matplotlib.units as units
import matplotlib.dates as dates
import matplotlib.ticker as ticker
import datetime
class DateConverter(units.ConversionInterface):
def axisinfo(unit):
'return the unit AxisInfo'
if unit=='date':
majloc = dates.AutoDateLocator()
majfmt = dates.AutoDateFormatter(majloc)
return units.AxisInfo(
majloc = majloc,
majfmt = majfmt,
label='date',
)
else: return None
axisinfo = staticmethod(axisinfo)
def convert(value, unit):
if units.ConversionInterface.is_numlike(value): return value
return dates.date2num(value)
convert = staticmethod(convert)
def default_units(x):
'return the default unit for x or None'
return 'date'
default_units = staticmethod(default_units)
# Once we have provided the basic required interface, we need to
# register it with matplotlib so the matplotlib code knows how to
# convert date and datetime objects to matplotlib floats.
units.registry[datetime.date] = DateConverter()
units.registry[datetime.datetime] = DateConverter()
\end{lstlisting}
Now we are ready to use native python date objects with matplotlib.
If we put the above in a modulke called \code{datesupport}, we can use
datetime object in matplotlib code as follows
\begin{lstlisting}
import datesupport # set up the date converters
import datetime
from matplotlib.dates import drange
from pylab import figure, show, nx
xmin = datetime.date(2007,1,1)
xmax = datetime.date.today()
delta = datetime.timedelta(days=1)
xdates = drange(xmin, xmax, delta)
fig = figure()
fig.subplots_adjust(bottom=0.2)
ax = fig.add_subplot(111)
ax.plot(xdates, nx.mlab.rand(len(xdates)), 'o')
ax.set_xlim(datetime.date(2007,2,1), datetime.date(2007,3,1))
fig.autofmt_xdate()
show()
\end{lstlisting}
In addition to custom types, in the same units infrastructure
matplotlib supports unit types; that is, objects which know how to
convert themselves to scalars given a unit argument. Because there is
no standard python units package, we do not assume any particular form
of the units. Rather, \code{matplotlib.axis.Axis} stores a
\code{units} property (which can be an arbitrary type) and will pass
this value of the units property to objects which are registered with
the units registry. The units conversion interface provides the
default do-nothing method
\begin{lstlisting}
def convert(obj, unit):
"""
convert obj using unit. If obj is a sequence, return the
converted sequence. The ouput must be a sequence of scalars
that can be used by the numerix array layer
"""
return obj
convert = staticmethod(convert)
\end{lstlisting}
to support unit conversions. The implementor is free to ignore the
\code{unit} argument which defaults to None. But if you set the
\code{unit} property (eg to \code{inches}), this will be passed to
your unit enabled objects registered with the units registry. Below
is a toy example in which a unit enabled class \code{Foo} is plotted
with different units (here the ``units'' are simple scalars 1.0, 2.0,
etc... but in real code would likely be strings like 'inches', 'cm' or
object instances like \code{inches}, \code{cm}\dots.
\begin{lstlisting}
from matplotlib.cbook import iterable
import matplotlib.units as units
import matplotlib.ticker as ticker
from pylab import figure, show, nx
class Foo:
def __init__( self, val, unit=1.0 ):
self.unit = unit
self._val = val * unit
def value( self, unit ):
if unit is None: unit = self.unit
return self._val / unit
class FooConverter:
def axisinfo(unit):
'return the Foo AxisInfo'
if unit==1.0 or unit==2.0:
return units.AxisInfo(
majloc = ticker.IndexLocator( 4, 0 ),
majfmt = ticker.FormatStrFormatter("VAL: %s"),
label='foo',
)
else:
return None
axisinfo = staticmethod(axisinfo)
def convert(obj, unit):
"""
convert obj using unit. If obj is a sequence, return the
converted sequence
"""
if units.ConversionInterface.is_numlike(obj):
return obj
if iterable(obj):
return [o.value(unit) for o in obj]
else:
return obj.value(unit)
convert = staticmethod(convert)
def default_units(x):
'return the default unit for x or None'
if iterable(x):
for thisx in x:
return thisx.unit
else:
return x.unit
default_units = staticmethod(default_units)
units.registry[Foo] = FooConverter()
# create some Foos
x = []
for val in range( 0, 50, 2 ):
x.append( Foo( val, 1.0 ) )
# and some arbitrary y data
y = [i for i in range( len(x) ) ]
# plot specifying units
fig = figure()
fig.subplots_adjust(bottom=0.2)
ax = fig.add_subplot(111)
ax.plot( x, y, 'o', xunits=2.0 )
for label in ax.get_xticklabels():
label.set_rotation(30)
label.set_ha('right')
# plot without specifying units; will use the None branch for axisinfo
fig2 = figure()
ax = fig2.add_subplot(111)
ax.plot( x, y ) # uses default units
fig3 = figure()
ax = fig3.add_subplot(111)
ax.plot( x, y, xunits=0.5)
show()
\end{lstlisting}
In the matplotlib examples directory, there is a mockup units package
\code{basic\_units}. While this is not designed for production use and
is not meant to be expanded upon, it does illustrate how one can use
unit enabled arrays with matplotlib with default axis labeling and
ticking. Here is an example using the \code{basic\_units} code for
plotting with radians and degrees; not the axis labels are set
``automagically''
\fig{4in}{figures/radian_demo}{Basic units: radians and degrees; see
Listing~\ref{lst:radian_demo}.}{fig:radian_demo}
\lstinputlisting[linerange=1-12,caption={Working with units and conversions Figure~\ref{lst:radian_demo}},
label=lst:radian_demo]{code/radian_demo.py}
Unit information is stored by the XAxis and YAxis instance using the
\code{units} property. This property can be set implicitly by passing
the \carg{xunits} or \carg{yunits} keyword arguments to the plotting
functions, eg
\begin{lstlisting}
ax.plot(cms, cms, xunits=cm, yunits=inch)
\end{lstlisting}
or set explicitly using the axis \code{set\_units} method, eg
\begin{lstlisting}
ax.xaxis.set_units(cm)
\end{lstlisting}
When units are reset, the matplotlib artists will attempt to convert
themselves to the new unit, eg \code{cm} to \code{inch} conversions
shouldbe fine, and \code{cm} to \code{Hz} conversions should raise an
exception. Whether an exception is actually raise and what that
exception is is the province of the underlying units package, since,
as indicated above, matplotlib makes no assumption about the
underlying units functionality other than it's interface as specified
by \mpldoc{units.ConversionInterface}.
\chapter{Cookbook}
\label{cha:cookbook}
\section{Plot elements}
\subsection{Horizontal or vertical lines/spans}
\label{cbook:axhv_line_span}
It is often useful to draw a line that stretches from the left to the
right side of the axes at a given height, eg to represent a y-axis
threshold. In this case, the left and right are plotted in axes
coordinates (0 and 1 respectively), and the y coordinate is in data
coordinates. Plotted this way, the horizontal extent of the line will
not change if you interactively change the xlimits, eg by using the
pan navigation tool. Although you can create these lines yourself
using \mpldoc{matplotlib.lines.Line2D} instances and setting the
appropriate transforms, several helper functions are provided to make
this easier.
\subsection{Fill the area between two curves}
\label{cbook:fill_between}
\fig{4in}{figures/fill_between}{Fill the area between two curves; see
Listing~\ref{lst:fill_between}.}{fig:fill_between}
\lstinputlisting[linerange=1-10,caption={Fill the area between two
curves; see Figure~\ref{lst:fill_between}},
label=lst:fill_between]{code/fill_between.py}
The fill command takes a list of vertices and draws a polygon. A
filled area between two curves is simply a large polygon. All you
need to do is get the vertices in the correct order, which basically
means reversing the order of the x,y pairs in one of the lines, so
that path across the vertices of the polygon is continuous. Here is a
simple example
\subsection{Drawing true ellipses and circles}
\label{cbook:true_ellipses}
The \code{matplotlib.patches.Ellipse} class, and the special case
derived class \code{matplotlib.patches.Circle} use 4 cubic splines to
approximate a true ellipse, which gives a very close approximation to
ellipses and is scale free. With a polygonal representation, you can
see the discreteness of the approximation as you zoom into the
vertices of the polygon.
\fig{4in}{figures/ellipse_demo}{Drawing true ellipses using spline, rather than polygonal, representations; see
Listing~\ref{lst:ellipse_demo}.}{fig:ellipse_demo}
\lstinputlisting[linerange=1-19,caption={The Ellipse patch
approximates true ellipses using 4 cubic splines, which is much more
accurate than a high resolution polygon representation.
SeeFigure~\ref{lst:ellipse_demo}},
label=lst:ellipse_demo]{code/ellipse_demo.py}
\section{Text}
\subsection{Adding a ylabel on the right of the axes}
\label{cbook:ylabel_right}
To make a ylabel on the right, use the \func{text} command. You need
to set the transform to use axes coordinates (\code{ax.transAxes}),
rotate the text vertically, make the horizontal alignment left, the
vertical alignment centered. Note that x, y = 1, 0.5 is the right,
middle of the axes in axes coordinates. You also need to turn off
clipping, so the text can appear outside the axes w/o being clipped by
the axes bounding box, which is the default behavior.
\begin{lstlisting}
text(1.02, 0.5, 'volts',
horizontalalignment='left',
verticalalignment='center',
rotation='vertical',
transform=gca().transAxes,
clip_on=False)
\end{lstlisting}
\section{Data analysis}
\subsection{Linear regression}
\label{cbook:linear_regression}
One of the most common tasks in analyzing data is a linear regression
of one variable on another. matplotlib provides \func{polyfit} in the
\mpldoc{matplotlib.mlab} module for general polynomial regression.
\fig{4in}{figures/linear_regression}{Estimating a best fit line for
some random data; see
Listing~\ref{lst:linear_regression}.}{fig:linear_regression}
\lstinputlisting[linerange=1-17,caption={Best fit line;
see Figure~\ref{fig:linear_regression}},
label=lst:linear_regression]{code/linear_regression.py}
\subsection{Polynomial regression}
\label{cbook:polynomial_regression}
polyfit can also be used for general polynomial fitting. The
signature of polyfit is \code{coeffs = polyfit(x, y, N)} where $N$ is
the order of the polynomial. The best fit can be obtained from the
coefficients and the x data using \code{best = polyval(x, coeefs)}.
\code{coeffs} are the coefficients of the polynomial $coeffs = p_k,
\dots, p_1, p_0$.
\fig{4in}{figures/poly_regression}{Estimating a best fit cubic for
some random data; see Listing~\ref{lst:poly_regression}}{fig:poly_regression}
The algorithm for polyfit is taken from Mathworld's \textit{Least
Squares Fitting Polynomial} and \textit{Vandermonde Matrix} entries
\citep{Weisstein2002}.
To do a best fit polynomial regression of order $N$ of $y$ onto $x$.
We must solve an $N$-dimensional system of equations; eg, for $N=2$
\begin{eqnarray}
\label{eq:polysys}
p_2*x_0^2 + p_1*x_0 + p_0 &=& y_1\nonumber\\
p_2*x_1^2 + p_1*x_1 + p_0 &=& y_1\nonumber\\
p_2*x_2^2 + p_1*x_2 + p_0 &=& y_2\nonumber\\
\dots & \nonumber\\
p_2*x_k^2 + p_1*x_k + p_0 &=& y_k\nonumber
\end{eqnarray}
\noindent If $X$ is a the Vandermonde Matrix computed from $x$, then the
polynomial least squares solution is given by the $p$ in $X*p = y$
where $X$ is a $x$ by $N+1$ matrix, $p$ is a $N+1$ length vector, and
$y$ is a len($x$) by 1 vector. This equation can be solved as
\begin{equation}
p = (\bar{X} X)^{-1} * \bar{X} * y
\end{equation}
\noindent where $\bar{X}$ is the transpose of X and the -1 superscript
denotes the inverse. For more info, see
Mathworld\footnote{\url{http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html}},
but note that the $k$'s and $n$'s in the superscripts and subscripts
on that page are problematic. The linear algebra is correct, however.
\lstinputlisting[linerange=1-16,caption={est fit polynomial; see
Figure~\ref{fig:poly_regression}},
label=lst:poly_regression]{code/poly_regression.py}
\section{Working with images}
\subsection{Loading existing images into matplotlib}
\label{cbook:image_files}
Currently matplotlib only supports plotting images from numerix
arrays, either luminance, RGB or RGBA. If you have some existing data
in an image file format such as PNG, JPEG or TIFF, you can load this
into matplotlib by first loading the file into PIL -
\url{http://www.pythonware.com/products/pil} and then converting this
to a numerix array using fromstring / tostring methods
\lstinputlisting{code/from_pil.py}
\subsection{Blending several axes images using alpha}
\label{cbook:layer_images}
You can compose several axes images on top of one another using alpha
blending, as described in Section~\ref{sec:image_axes}. If your
\func{hold} state is \val{True}, multiple calls to
\func{imshow} will cause the image arrays to be resampled to the
axes bounding box and blended. Of course, the uppermost images must
have alpha less than one, or else they will be fully opaque and hence
the lower images will be invisible. Note that you can blend images
from arrays of different shapes as well as blending images with
different colormaps and interpolation schemes. The example below
creates a black and white checkboard using a grayscale colormap and
then blends a color image over it, as shown in
Figure~\ref{fig:layer_images}.
\fig{4in}{figures/layer_images}{Layering axes images using alpha
blending; see Listing~\ref{lst:layer_images}.}
{fig:layer_images}
\lstinputlisting[linerange=1-25,caption={Alpha-blending multiple images;
see Figure~\ref{fig:layer_images}},
label=lst:layer_images]{code/layer_images.py}
\subsection{Creating a mosaic of images}
\label{cbook:figure_mosaic}
You can compose several figure images into a mosaic using the
\func{figimage} command, as discussed Section~\ref{sec:image_figure}. If
your \func{hold} state is \val{True}, multiple calls to
\code{figimage(X, xo, yo)}. xo and yo are the pixel offsets from
the origin (the origin can be either upper left or lower left, as
discussed in Section~\ref{sec:image_origin}). The code below using color
mapping to place two images on the diagonal. Note that you can use
different kinds of arrays (luminance, RGB, RGBA) and different
colormaps when creating figure mosaics. See
Figure~\ref{fig:figure_mosaic}.
\fig{4in}{figures/figure_mosaic}{Creating a mosaic using
\func{figimage}; see Listing~\ref{lst:figure_mosaic}.}
{fig:figure_mosaic}
\lstinputlisting[linerange=1-8,caption={Creating figure mosaics;
see Figure~\ref{fig:figure_mosaic}},
label=lst:figure_mosaic]{code/figure_mosaic.py}
\subsection{Defining your own colormap}
Perry Greenfield has provided a nice framework with
\mpldoc{matplotlib.colors.LinearSegmentedColormap} to define new
colormaps. You can create new colormaps fairly easy by following the
example of jet in \mpldoc{matplotlib.cm}. Here are the steps
\begin{itemize}
\item define your rgb linear segments in \mpldoc{matplotlib.cm},
following the lead of the \val{\_jet\_data} dictionary in that module
\item add an entry to the datad dictionary in that module which maps
rc string names for your color map to the dictionary you just
defined.
\item instantiate a single instance of your colormap in cm, following
the example
\begin{lstlisting}
jet = colors.LinearSegmentedColormap('jet', _jet_data, LUTSIZE)
\end{lstlisting}
\item{add a pylab function which has the same name as your
colormap, following the example of \mpldoc{pylab.jet}.}
\end{itemize}
\noindent Now anyone can use the colormap interactively from the shell, by
setting it as the default image.cmap in rc, etc. Please submit your
changes to the matplotlib-devel mailing list.
\section{Output}
\label{sec:output}
\subsection{Printing to standard output}
\label{cbook:print_stdout}
In some instances, it is nice to be able to print to a file object, eg
\code{sys.stdot}, for example in a web application server where the
creation of a temporary file storing the images is a wasted step. The
antigrain backend accepts a file object to the \func{savefig} command
and will print a PNG to it. Thus to print to standard output, you
could do
\begin{lstlisting}
import sys
import matplotlib
# this is not supported across all backends, as of matplotlib-0.63
matplotlib.use('Agg')
from pylab import *
plot([1,2,3])
savefig(sys.stdout)
\end{lstlisting}
\chapter{Matplotlib API}
\label{cha:api}
The pylab interface does a lot of work for you under the hood,
creating and managing multiple figure windows, directing your plotting
commands to the current axes and figure, managing the interactive
state, and so on. But that is all it does: all of the plotting is
handled by a set of classes that the user can instantiate directly.
If you are developing a GUI application, or simply don't want any
hidden magic in your plots, you can create any plots using pure OO
code that you could create with the pylab interface.
From a developer standpoint, the pylab interface has been a blessing
in disguise. Because the interface was fixed by the Mathworks before
the start of matplotlib provided considerable freedom to redesign the
guts of the plotting library -- the object model can be totally
revamped and the user interface remains fixed.
The matplotlib code is divided conceptually into 3 parts: the \matlab\
interface, the matplotlib Artists, and the backend renderers. The
\textit{pylab interface} was covered in
Chapter~\ref{cha:matlab_interface}. This module
\mpldoc{pylab} is comprised mainly of code to manage the
multiple figure windows across backends, and provide a thin,
procedural wrapper around the object oriented plotting code. The
\textit{matplotlib Artists} are a series of classes that derive from
\mpldoc{matplotlib.artist.Artist}, so named because these are the
objects that actually draw into the figure; see
Figure~\ref{fig:artist}. The \textit{backend renderers} each
implement a common drawing interface that actually puts the ink on the
paper, eg creating a postscript document, filling an antigrain pixel
buffer, or calling the gtk drawing code.
This chapter delves into matplotlib internals to give a clearer
picture of how things work and how they are organized. Some of this
material may be of interest only to developers, but most of it should
shed light for anyone who wants to be able to exploit the full
capabilities of matplotlib. The normal path of figure creation in
matplotlib is pylab interface $\rightarrow$ creates artists
$\rightarrow$ calls to the backend renderer. This section will invert
that process, starting with the backend, which is where the drawing
actually takes place. This is the natural order of presentation
because the backend knows nothing about Artists, which in turn known
nothing about the pylab interface. After the overview of the backend
API, there is a discussion of the matplotlib artists; this is the
section that is most useful to users, particularly those who want to
embed matplotlib in an application. The final section shows how the
pylab interface controls the backends and artists -- this section is
probably of interest to developers and the terminally curious.
\section{The matplotlib backends}
\label{sec:api_backends}
The backend consists of a number of related base classes that together
define a drawing API. The original backend was GTK, and the drawing
API is heavily based on the GTK drawing model, which is very simple.
There are three essential classes defined in
matplotlib.backend\_bases: \class{RendererBase},
\class{GraphicsContextBase} and \class{FigureCanvasBase}. In
addition, there are some classes for use with the GUI backends to
define the interface to the toolbars and event handling. The
\class{RendererBase}, aka \textit{renderer} handles all the drawing
primitives in display coordinates, typical renderer methods are
\func{draw\_text} and \func{draw\_lines}. The
\class{GraphicsContextBase}, aka textit{graphics context} stores
information about the graphics properties, such as linewidth, cap or
join style, color, alpha translucency. The \class{FigureCanvasBase},
aka \textit{figure canvas}, is primarily a container class to hold the
\class{Figure} instance; this facilitates separation of the Figure
from the backend dependent code. For GUI backends, the figure canvas
should be a GUI widget embeddable in a GUI window.
\subsection{The renderer and graphics context}
\label{sec:renderer}
The renderer defines the low-level matplotlib drawing API; all of the
drawing commands are done in display coordinates. The matplotlib
Artist classes handle all of the layout and transformation issue, and
pass the primitive drawing commands on to the renderer. The renderers
know nothing about the matplotlib Artists, and nothing about the
pylab interface. Their one and only job is to get ink onto the
canvas. The graphics context stores information about the objects to
be drawn, their color, linewidths, cap and join styles, alpha
transparency, etc. Taken together, you can use the backend renderer
and graphics context directly to make drawings. This may not be
advisable, since the whole purpose of the matplotlib Artists and
pylab interface is to simplify the process of getting ink onto the
canvas, but it is possible. However, it is potentially useful to
developers who may want to extend the capabilities of matplotlib, eg,
to implement block diagram drawing.
Every backend in \fname{matplotlib/backends} defines a
\class{Renderer} that inherits from \mpldoc{RendererBase}; some also
define a backend dependent \class{GraphicsContext}, while other simply
use the \mpldoc{GraphicsContextBase} for storing the information and
do all the work of translating these values in the \class Renderer.
This is the approach the Agg backend uses, shown in the listing below.
\fig{3in}{figures/renderer_agg}{Drawing directly with the backend
renderer and graphics context; see
Listing~\ref{lst:renderer_agg}}{fig:renderer_agg}
\lstinputlisting[caption={Drawing with the agg renderer; see
Figure~\ref{fig:renderer_agg}},
label=lst:renderer_agg]{code/renderer_agg.py}
\subsection{The figure canvases}
\label{sec:figurecanvas}
\fig{5in}{figures/FigureCanvas}{The inheritance diagram for The
FigureCanvas hierarchy. The FigureCanvas is a backend dependent
class which contains a figure instance. For GUI backends, the
canvas should be a GUI widget embeddable in a GUI window. Some of
the GUIs have backends with both native drawing and antigrain
drawing (GTK/GTKAgg, WX/WXAgg), which is readily achieved with
multiple inheritance. }{fig:figurecanvas}
\section{The matplotlib Artists}
\label{sec:artists}
\fig{4in}{figures/artist}{The matplotlib Artist hierarchy. The
primitive Artists are the Patches, Line2D, Text, AxesImage,
FigureImage and Collection classes. All other artists are
composites of these. For example a Tick is comprised of a Line2D
instance and a Text instance, which make up the tick line and tick
label; the Axis is comprised of a list of Ticks and a Text axis
label; see Figure~\ref{fig:containment}.}{fig:artist}
\fig{6in}{figures/containment}{The Artist containment hierarchy. The
top level Artist is the \mpldoc{matplotlib.figure.Figure}, which
contains all of the other Artist instances. The attribute names are
given in lower case, and the object type is listed below in upper
case. If the attribute is a sequence, for example the figure
contains a list of Axes, then the connecting edge is labeled $0\dots
n$ and the object type is in square brackets to indicate a list, eg
[Axes]. Some redundant information is omitted; for example, the
yaxis contains the equivalent objects that the xaxis contains, the
minorTicks have the same containment hierarchy as the majorTicks,
and so on. }{fig:containment}
\section{pylab interface internals}
Let's look at the simplest matplotlib script and walk through what
happens under the hood. This section will be of interest mainly to
developers or those curious about matplotlib internals - it can be
safely skipped by others. We'll assume you are using one of the GUI
backends, eg GTKAgg and have are running this as a script
(\rc{interactive : False})
\begin{lstlisting}
from pylab import *
plot([1,2,3])
show()
\end{lstlisting}
\subsection*{Line 1: \texttt{from pylab import *}}
When any matplotlib code is imported the first time, the
\fname{matplotlib.\_\_init\_\_.py} code is called. The primary thing
the init code does is find and parse your rc file, or if it fails fall
back on a set of default parameters. Once this is done,
\mpldoc{pylab} proceeds to import all of the
\mpldoc{matplotlib.numerix} and \mpldoc{matplotlib.mlab} symbols into
the namespace, and loads the backend from
\mpldoc{matplotlib.backends}, which use the rc information to load
four functions from the backend module specified by the rc
\rc{backend} parameter. The pylab interface requires only four
functions from the backend: \func{new\_figure\_manager},
\func{error\_msg}, \func{draw\_if\_interactive}, and \func{show}
\begin{itemize}
\item \func{new\_figure\_manager} is responsible for creating a new
instance from a backend dependent class derived from
\mpldoc{matplotlib.backend\_bases.FigureManager}; this class wraps
GUI window creation and management.
\item \func{error\_msg} displays an error message; for image backends
this message is printed to the file object determined by the rc
parameter \rc{verbose.erro} and for GUI backends it is typically
displayed in a GUI dialog box.
\item \func{draw\_if\_interactive} is called after every
\mpldoc{pylab} drawing command (\func{plot}, \func{set},
\func{xlim}, \dots) and updates the figure window with the new
information only if \rc{interactive} is \val{True}.
\item \func{show} raises all the GUI figure windows and triggers a
command to draw the figure.
\end{itemize}
\noindent The pylab interface also imports a \class{Gcf} instance from the
\mpldoc{matplotlib.\_matlab\_helpers} module, which manages the
current figure and current axes. The pylab interface defines
\func{gcf} and \func{gca} to get a reference to the current figure and
axes, which in turn are interfaces to the \class{Gcf} class that does
the real lifting.
\subsection*{Line 2: \texttt{plot([1,2,3])}}
All of the \mpldoc{pylab} functions are defined similarly:
they get the current axes and forward the call on to the corresponding
\mpldoc{matplotlib.axes.Axes} method, which does the real work. The
\func{plot} command in the example below calls \func{gca} to get the
current axes. If no figure or axes has been defined at the time of
this call, the are created one on the fly using default parameters
from the rc file; ultimately the \func{new\_figure\_manager} backend
method is called to provide new figures when needed, and the default
\code{subplot(111)} is added to the figure if no other axes has been
defined.
The \func{new\_figure\_manager} method deserves a bit more attention,
because this creates the central object that contains all the other
objects relevant to the creation of a single figure.
\mpldoc{matplotlib.backend\_bases.FigureManagerBase} is a container
class for the figure window (a GUI window) and figure canvas (a GUI
widget which can be drawn upon). The figure canvas derives from
\mpldoc{matplotlib.backend\_bases.FigureCanvasBase}, and contains the
\mpldoc{matplotlib.figure.Figure} instance.
\fig{3in}{figures/manager}{The pylab interface function
\func{new\_figure\_manager} returns a backend dependent concrete
implementation of
\mpldoc{matplotlib.backend\_bases.FigureManagerBase}, which contains
the figure canvas and figure window. The attribute names are shown
in lower case, and the backend dependent classes are shown in upper
case. The standard attribute naming system allows the \matlab\
interface to make calls across backends to the figure canvas and
figure.}{fig:manager}
Once the current axes is obtained by \func{gca}, \func{plot} forwards
the call to \func{Axes.plot}. If an exception is raise, the backend
\func{error\_msg} method is called with the traceback to display it.
If the code is successful, the backend \func{draw\_if\_interactive}
method is called which will update the plot if the rc parameter
\rc{interactive} is \val{True}, and finally the return value is
returned.
\begin{lstlisting}
def plot(*args, **kwargs):
try:
lines = gca().plot(*args, **kwargs)
except ValueError, msg:
msg = raise_msg_to_str(msg)
error_msg(msg)
else:
draw_if_interactive()
return lines
plot.__doc__ = Axes.plot.__doc__
\end{lstlisting}
The \func{matplotlib.axes.Axes.plot} method parses the \code{*args}
and {**kwargs}, creates the requested line objects, and adds them to
its list of \class{Line2D} instances. It will also extract the x and
y data range and use these to update the data limits of the axes,
which is turn will be used to autoscale the view limits. No drawing
code is actually issued, but is deferred until later.
\subsection*{Line 3: \texttt{show()}}
\func{show} is an interface to realize and show the GUI windows. For
image backends, eg Agg, PS or SVG, it is superfluous. The image
backends will draw the figure on a call to savefig, and ignore a
\func{show} call. Each GUI backend defines \func{show} to realize all
of the GUI windows, and start the GUI mainloop. For this reason, the
call to \func{show} is blocking, and should be the last line of the
script. Here is a representative show method from
\mpldoc{matplotlib.backends.backend\_gtk}
\begin{lstlisting}
def show(mainloop=True):
"""
Show all the figures and enter the gtk main loop
This should be the last line of your script
"""
for manager in Gcf.get_all_fig_managers():
manager.window.show()
if gtk.main_level() == 0 and mainloop:
if gtk.pygtk_version >= (2,4,0): gtk.main()
else: gtk.mainloop()
\end{lstlisting}
Typically, the GUI backends binds the realize or expose event of the
GUI window to ultimately trigger the \func{Figure.draw} method of the
Figure instance contained by the \class{FigureCanvas}. In the show
function above, \code{manager.window.show()} will trigger an expose
event in pygtk. The gtk backend binds the expose event to the
\func{FigureCanvasGTK.expose\_event} method. If the canvas has not yet
been drawn, the \func{expose\_event} method will create a RendererGTK
instance (which derives from the common drawing API in
\mpldoc{matplotlib.backends.RendererBase}) and then call
\func{Figure.draw(renderer)}, which in turn passes the draw command on
to each \class{Artist} instance it contains; see
Figure~\ref{fig:containment} for the \class{Artist} containment
hierarchy. Each \class{Artist} instance defines the draw method, and
contains a transform to transform itself to display coordinates. For
example, the Line2D instance will transform its x and y data to
display coordinates, and then call the appropriate renderer method, eg
\func{RendererGTK.draw\_lines}, which expects x and y data in display
coordinates. In this case, the GTK renderer \func{draw\_lines} method makes
the appropriate calls to the GTK drawing API, and the screen is
updated; see Figure~\ref{fig:show}.
\fig{6in}{figures/show}{The typical sequence of steps triggered in the
backend code by the call to \func{show} that ultimately gets the ink
on the canvas.}{fig:show}
\appendix
\chapter{A sample \fname{matplotlibrc}}
\label{cha:rc}
\lstinputlisting{code/matplotlibrc}
\chapter{mathtext symbols}
\label{cha:math_symbols}
\chapter{matplotlib source code license}
\label{cha:license}
matplotlib is distributed under the Python Software Foundation (PSF)
license, which permits commercial and noncommercial free use and
redistribution as long as the conditions below are met. The VERSION
string below is replaced by the current matplotlib version number
with each release.
\begin{verbatim}
LICENSE AGREEMENT FOR MATPLOTLIB VERSION
--------------------------------------
1. This LICENSE AGREEMENT is between the John D. Hunter ("JDH"), and the
Individual or Organization ("Licensee") accessing and otherwise using
matplotlib software in source or binary form and its associated
documentation.
2. Subject to the terms and conditions of this License Agreement, JDH
hereby grants Licensee a nonexclusive, royalty-free, world-wide license
to reproduce, analyze, test, perform and/or display publicly, prepare
derivative works, distribute, and otherwise use matplotlib VERSION
alone or in any derivative version, provided, however, that JDH's
License Agreement and JDH's notice of copyright, i.e., "Copyright (c)
2002-2007 John D. Hunter; All Rights Reserved" are retained in
matplotlib VERSION alone or in any derivative version prepared by
Licensee.
3. In the event Licensee prepares a derivative work that is based on or
incorporates matplotlib VERSION or any part thereof, and wants to
make the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to matplotlib VERSION.
4. JDH is making matplotlib VERSION available to Licensee on an "AS
IS" basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB VERSION
WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
VERSION FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
MATPLOTLIB VERSION, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any
relationship of agency, partnership, or joint venture between JDH and
Licensee. This License Agreement does not grant permission to use JDH
trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.
8. By copying, installing or otherwise using matplotlib VERSION,
Licensee agrees to be bound by the terms and conditions of this License
Agreement.
\end{verbatim}
\bibliographystyle{plainnat}
\bibliography{matplotlib}
\end{document}