0% found this document useful (0 votes)
232 views6 pages

J. D. Hunter 2007 Matplotlib A 2D Graphics en

Matplotlib is a 2D graphics package for Python used for application development, interactive scripting, and publication-quality image generation. It was created to provide a graphics environment similar to MATLAB but with additional functionality like being embeddable in GUIs and supporting multiple platforms. Matplotlib can generate plots, images, contours, and colorbars and supports mathematical text rendering through LaTeX integration. A simple example shows basic line plotting in IPython using Matplotlib's MATLAB-like plotting interface.

Uploaded by

Ahmad Shamy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
232 views6 pages

J. D. Hunter 2007 Matplotlib A 2D Graphics en

Matplotlib is a 2D graphics package for Python used for application development, interactive scripting, and publication-quality image generation. It was created to provide a graphics environment similar to MATLAB but with additional functionality like being embeddable in GUIs and supporting multiple platforms. Matplotlib can generate plots, images, contours, and colorbars and supports mathematical text rendering through LaTeX integration. A simple example shows basic line plotting in IPython using Matplotlib's MATLAB-like plotting interface.

Uploaded by

Ahmad Shamy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 6

SCIENTIFIC PROGRAMMING

Editors: George K. Thiruvathukal, gkt@cs.luc.edu


Konstantin Läufer, laufer@cs.luc.edu

MATPLOTLIB:
A 2D GRAPHICS ENVIRONMENT
By John D. Hunter

Matplotlib is a 2D graphics package used for Python for application development, interactive scripting,
and publication-quality image generation across user interfaces and operating systems.

I began learning Python in 2001, mainly as a way to pro-


crastinate during the final stages of preparing my dis-
sertation. I was hooked in short order. My numerical
and statistical workflow at the time was a mix of Fortran,
C++, and Matlab; I used the file system to communicate be-
in a GUI for application development, support different
platforms, offer extremely high-quality raster and vector
(primarily PostScript) hardcopy output for publication, pro-
vide support for mathematical expressions, and work inter-
actively from the shell.
tween the three. Python’s ability to integrate seamlessly and I wrote matplotlib to satisfy these needs, concentrating
transparently with high-performance compiled code dra- initially on the first requirement so I could get up and run-
matically simplified this workflow, but I couldn’t quite wean ning with my ECoG application (the pbrain component of
myself from the breadth, quality, and ease of use that the the “neuroimaging in Python project” at http://nipy.scipy.
Matlab environment offered for graphics. org; also, see p. 52 in this issue) and then gradually adding
Around that time, I began a fairly substantial project that support for the others, with generous contributions from
involved writing an application to analyze human electro- the matplotlib community. Because I was intimately famil-
corticography (ECoG) signals registered with 3D medical iar with Matlab and happy with its graphics environment, I
image data, and I debated long and hard about using followed the advice of Edward Tufte (“copy the great archi-
Python or Matlab. On balance—and after much hand tectures”) and T.S. Elliot (“talent imitates, but genius
wringing—Matlab won, primarily because of its excellent steals”) and reverse-engineered the basic Matlab interface.
graphics and secondarily because of its widespread use in Figure 1 shows a screenshot of the pbrain ECoG viewer I
the ECoG community. The application quickly grew in wrote in matplotlib.
complexity, ultimately incorporating 3D medical image vi- The latest release of matplotlib runs on all major operat-
sualizations, 2D ECoG displays, spectral and time-series ing systems, with binaries for Macintosh’s OS X, Microsoft
analyses, and the data structures required to represent hu- Windows, and the major Linux distributions; it can be em-
man subject data. The networking support included data bedded in GUIs written in GTK, WX, Tk, Qt, and FLTK;
files served up over HTTP, metadata served up over has vector output in PostScript, Scalable Vector Graphics
MySQL, and some Web Common Gateway Interface (SVG), and PDF; supports TeX and LaTeX for text and
(CGI) forms thrown into the mix for good measure. Not mathematical expressions; supports major 2D plot types and
everyone knows that Matlab embeds its own Java Virtual interactive graphics, including xy plots, bar charts, pie
Machine (JVM), which makes it possible to handle all of charts, scatter plots, images, contouring, animation, pick-
these things, but making them work together became in- ing, event handling, and annotations; and is distributed un-
creasingly painful, and I eventually hit the wall and decided der a permissive license based on the one from the Python
to start all over again in Python. Software Foundation. Along with a large community of
The first step was to find a suitable replacement for the users and developers, several institutions also use and sup-
Matlab 2D graphics engine (the Visualization Toolkit port matplotlib development, including the Space Telescope
[VTK] in Python provided 3D-visualization support that Science Institute and the Jet Propulsion Laboratory.
was more than adequate for my purposes). Although a score
of graphics packages were and are readily available for Getting Started: A Simple Example
Python, none met all my needs: they had to be embeddable Matplotlib has a Matlab emulation environment called

90 Copublished by the IEEE CS and the AIP 1521-9615/07/$25.00 © 2007 IEEE COMPUTING IN SCIENCE & ENGINEERING
PyLab, which is a simple wrapper of the matplotlib API. Al-
though many die-hard Pythonistas bristle at PyLab’s Mat-
lab-like syntax and its from pylab import * examples,
which dump the PyLab and NumPy functionality into a sin-
gle namespace for ease of use, this feature is an essential sell-
ing point for many teachers whose students aren’t
programmers and don’t want to be: they just want to get up
and running. For many of these students, Matlab is the only
exposure to programming they’ve ever had, and the ability
to leverage that knowledge is often a critical point for teach-
ers trying to bring Python into the science classroom. In Figure 1. The PBrain project. An electrocorticography
Figure 2 , I’ve enabled the usetex parameter in the mat- (ECoG) viewer, written in matplotlib and embedded in a
plotlib configuration file so LaTeX can generate both the pygtk application.
text and the equations.
Let’s look at a sample session from IPython, the interac-
tive Python shell that is matplotlib-aware in PyLab mode
(also see p. 21 in this issue):

> ipython -pylab


IPython 0.7.3 — An enhanced Interactive Python.
Welcome to pylab, a matplotlib-based
Python environment. For more information,
type ‘help(pylab)’.

In [1]: subplot(111)
In [2]: t = arange(0.0,3.01,0.01)
In [3]: s = sin(2*pi*t)
In [4]: c = sin(4*pi*t)
In [5]: fill(t, s, ‘blue’, t, c, ‘green’,
alpha=0.3);
In [6]: title(r’\TeX\ is
No.$\displaystyle\sum_{n=1}^\infty
\frac{-e^{i\pi}}{2^n}$!’) Figure 2. LaTeX support. Setting the usetex option in the
matplotlib configuration file enables LaTeX generation of
IPython detects which GUI windowing system you want the text and equations in a matplotlib figure, as this
to use by inspecting your matplotlib configuration, imports screenshot shows.
the PyLab namespace, and then makes the necessary thread-
ing calls so you can work interactively with a GUI mainloop
such as GTK’s. neighbor interpolation for those who just want to see their
raw data), “bilinear,” “bicubic,” and 14 other interpolation
Images, Color Mapping, methods for smoothing data. For color mapping, all the clas-
Contouring, and Color Bars sic color maps from Matlab are available (gray, jet, hot,
In addition to simple line plots, you can fairly easily create copper, bone, and so on) as well as scores more. You can
more sophisticated graphs, including color-mapped images also define custom color maps.
with contouring and labeling, in just a few lines of Python. Let’s look at a Python script that computes a bivariate
For pseudocolor images, matplotlib supports various image- Gaussian distribution plotted as a grayscale image and then
interpolation and color-mapping schemes. For interpola- overlays contour lines using the heated object scale hot
tion, you can choose “nearest” (which does a nearest color map:

MAY/JUNE 2007 91
SCIENTIFIC PROGRAMMING

cbar = fig.colorbar(cs, shrink=0.8,


extend=’both’)

# we can still add a colorbar for the image, too.


cbarim = fig.colorbar(im, orientation=
’horizontal’, shrink=0.8)

# This makes the original colorbar look a bit


Figure 3. Images, contours, and color mapping. This # out of place, so let’s improve its position.
screenshot from matplotlib illustrates how to add contour l,b,w,h = ax.get_position()
lines to luminosity images; note that the use of multiple ll,bb,ww,hh = cbar.ax.get_position()
color maps (gray and hot) and color bars (continuous cbar.ax.set_position([ll, b+0.1*h, ww, h*0.8])
and discrete) are supported.
show()

Figure 3 shows the output of this Python script, with mul-


from pylab import figure, cm, nx, show tiple color maps and color bars supported in a single axes, as
from matplotlib.mlab import meshgrid, \ well as continuous (the horizontal gray bar) and discrete
bivariate_normal color bars (the vertical hot bar).

delta = 0.025 Interactive Plotting


x = nx.arange(-3.0, 3.0, delta) To facilitate interactive work, matplotlib provides access to ba-
y = nx.arange(-2.0, 2.0, delta) sic GUI events, such as button_press_event, mouse
X, Y = meshgrid(x, y) _motion_event, key_press_event, draw_event, and so
Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) on; you can also register with these events to receive callbacks.
Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) In addition to the GUI-provided information, we attach mat-
Z = 10.0 * (Z2 - Z1) # difference of Gaussians plotlib-specific data—if you connect to the button_
press_event, for example, you can get the button press’s x
fig = figure() and y location in the display space, the xdata and ydata co-
ax = fig.add_subplot(111) ordinates in the user space, which axes the click occurred in,
and the underlying GUI event that generated the callback.
# make a grayscale image
im = ax.imshow(Z, interpolation=’bilinear’, Event Handling
cmap=cm.gray, extent=(-3,3,-2,2), Matplotlib abstracts GUI event handling across the five ma-
origin=’lower’) jor GUIs it supports, so event-handling code written in mat-
levels = nx.arange(-1.2, 1.6, 0.2) plotlib works across many different GUIs. Let’s look at a
simple example that reports the x and y locations in the dis-
# do a contour using a “hot” colormap for play and user spaces with a mouse click:
# the lines
cs = ax.contour(Z, levels, linewidths=2, from pylab import figure, show
cmap=cm.hot, extent=(-3,3,-2,2), fig = figure()
origin=’lower’) ax = fig.add_subplot(111)
ax.plot([1,2,3])
# label every 2nd contour inline
ax.clabel(cs, levels[1::2], inline=1, def onpress(event):
fmt=’%1.1f’) if not event.inaxes: return
print ‘click’
# make a colorbar for the contour lines print ‘\tuser space: x=%1.3f, y=%1.3f’%(

92 COMPUTING IN SCIENCE & ENGINEERING


event.xdata, event.ydata) ting functionality that’s either too big or too narrow in
print ‘\tdisplay space: x=%1.3f, y=%1.3f’%( purpose for the main distribution. Jeffrey Whitaker of
event.x, event.y) the US National Oceanic and Atmospheric Association
offers the excellent basemap toolkit for plotting data on
fig.canvas.mpl_connect(‘button_press_event’, map projections (http://matplotlib.sourceforge.net/mat
onpress) plotlib.toolkits.basemap.basemap.html). Some of the
show() available projections include cylindrical equidistant,
mercator, lambert conformal conic, lambert azimuthal
Basic events like button and key presses, mouse motion, equal area, albers equal area conic, stereographic, and
and canvas drawing are supported across the five GUIs that many others. The basemap toolkit ships with the proj4
matplotlib supports, thus matplotlib code written for one library and Python wrappers to do the projections.
GUI will port without changes to another. Coastlines, political boundaries, and rivers are available
in four resolutions: crude, low, intermediate, and high.
Picking The toolkit also supports contouring and annotations.
All matplotlib Artist primitives define a method pick that Figure 4 shows an orthographic map projection of the
supports picking so that users can interactively select objects Earth from the perspective of a satellite looking down at
in the plot scene via mouse clicks. Users can also define 50N, 100W using low-resolution coastlines and from
threshold tolerance criteria in distance units—for example, this code:
to define a hit if the mouse click is within five printer’s points
of the graphical object—or provide a custom hit-testing from matplotlib.toolkits.basemap import Basemap
function. Let’s print the data points that fall within five from pylab import nx, show
points of the mouse-click location:
# don’t plot features that are smaller than
from pylab import figure, nx, show # 1000 square km.
fig = figure() map = Basemap(projection=’ortho’,lat_0=50,
ax1 = fig.add_subplot(111) lon_0=-100, resolution=’l’,
area_thresh=1000.)
# 5 points tolerance
line, = ax1.plot(nx.mlab.rand(100), ‘o’, # draw coastlines, country boundaries, fill
picker=5) # continents.
map.drawcoastlines()
def onpick(event): map.drawcountries()
line = event.artist map.fillcontinents(color=’coral’)
xdata = line.get_xdata()
ydata = line.get_ydata() # draw the edge of the map projection region
ind = event.ind # (the projection limb)
print ‘data: ‘, zip(nx.take(xdata, ind), map.drawmapboundary()
nx.take(ydata, ind))
# draw lat/lon grid lines every 30 degrees.
fig.canvas.mpl_connect(‘pick_event’, onpick) map.drawmeridians(nx.arange(0,360,30))
show() map.drawparallels(nx.arange(-90,90,30))
show()
More elaborate examples, such as defining custom hit-
testing functions, are located in the examples directory of Many more sophisticated examples including annota-
the matplotlib source distribution. tions, alternate projections, and detailed political and geo-
graphic boundaries are available in the examples directory
Matplotlib Toolkits of the basemap toolkit, which also ships with shape files for
Matplotlib supports toolkits for domain-specific plot- the boundaries.

MAY/JUNE 2007 93
SCIENTIFIC PROGRAMMING

provides a rigid segregation between Figure and the out-


put formats. Let’s look at a complete example that uses the
Agg canvas to make a PNG output file:

from matplotlib.backends.backend_agg import \


FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot([1,2,3])
fig.savefig(‘agg_demo.png’)

Figure 4. Low-resolution satellite view of the Earth using To create a different output format, such as PostScript, we
the matplotlib basemap toolkit. Higher-resolution political need only change the first line to from matplotlib.back-
and geographic boundaries, as well as a wealth of map ends.backend_ps import FigureCanvasPS as Fig-
projections, are available as configuration options in the ureCanvas. The method canvas.draw() in our code
toolkit. example creates a back-end-specific renderer and forwards
the draw call to Figure. The draw method looks like this:

The Matplotlib API class FigureCanvasAgg(FigureCanvasBase):


At its highest level, the matplotlib API has three basic def draw(self):
classes: FigureCanvasBase is the canvas onto which the renderer = RendererAgg(self.width,
scene is painted, analogous to a painter’s canvas; self.height, ...)
RendererBase is the object used to paint on the canvas, self.figure.draw(renderer)
analogous to a paintbrush; and Artist is the object that
knows how to use a renderer to paint on a canvas. Artist Every Artist must implement the draw method; the call
is also where most of the interesting stuff happens; basic to Figure.draw calls Axes.draw for each Axes in the Fig-
graphics primitives such as Line2D, Polygon, and Text all ure. In turn, Axes.draw calls Line2D.draw for every line
derive from this base class. Higher-level artists such as in the Axes, and so on, until all the matplotlib Artists con-
Tick (for creating tick lines and labels) contain layout al- tained in the figure are drawn. Let’s look at the code for the
gorithms and lower-level primitive artists to handle the top-level Line2D.draw method, which closes the circle be-
drawing of the tick line (Line2D), grid line (Line2D), and tween the high-level matplotlib Artists and the low-level
tick label (Text). At the highest level, the Figure instance primitive renderer methods:
itself is an Artist that contains one or more Axes in-
stances—the subplot command in Figure 2 creates an class Line2D(Artist):
Axes instance. def draw(self, renderer):
The basic drawing pipeline is fairly straightforward. For x, y = self.get_transformed_xy()
concreteness, let’s look at the Agg back end. Agg is the core gc = renderer.new_gc()
matplotlib raster back end that uses the antigrain C++ ren- gc.set_foreground(self._color)
dering engine to create pixel buffers with support for anti- gc.set_antialiased(self._antialiased)
aliasing and alpha transparency (see www.antigrain.com). gc.set_linewidth(self._linewidth)
FigureCanvasAgg creates the pixel buffer, and Renderer gc.set_alpha(self._alpha)
Agg provides low-level methods for drawing onto the can- renderer.draw_lines(gc, x, y)
vas—for example, with draw_lines or draw_polygon.
The canvas is created with a reference to Figure, which This code illustrates the encapsulation of the back-end ren-
is the top-level Artist that contains all other artists. This derer from the matplotlib Artist: the Line2D class knows

94 COMPUTING IN SCIENCE & ENGINEERING


Advertising Sales Phone: +1 269 381 2156 Northwest (product)
Advertiser | Product Index Representatives Fax: +1 269 381 2556
Email: wh.ieeemedia@ieee.org
Peter D. Scott
Phone: +1 415 421-7950
May | June 2007 Mid Atlantic (product/recruit-
ment)
Joe DiNardo
Phone: +1 440 248 2456
Fax: +1 415 398-4156
Email: peterd@pscottassoc.com
Dawn Becker Fax: +1 440 248 2594
Phone: +1 732 772 0160 Email: jd.ieeemedia@ieee.org Southern CA (product)
Advertiser Page number Fax: +1 732 772 0164 Marshall Rubin
Email: db.ieeemedia@ieee.org Southeast (recruitment) Phone: +1 818 888 2407
AAPM 2007 Cover 3 Thomas M. Flynn Fax: +1 818 888 4907
LinuxWorld 2007 Cover 4 New England (product) Phone: +1 770 645 2944
Fax: +1 770 993 4423
Email: mr.ieeemedia@ieee.org
Jody Estabrook
Phone: +1 978 244 0192 Email: flynntom@mindspring.com Northwest/Southern CA (recruit-
Fax: +1 978 244 0103 ment)
*Boldface denotes advertisements in this issue Southeast (product) Tim Matteson
Email: je.ieeemedia@ieee.org
Bill Holland Phone: +1 310 836 4064
New England (recruitment) Phone: +1 770 435 6549 Fax: +1 310 836 4067
Advertising Personnel John Restchack Fax: +1 770 435 0243 Email: tm.ieeemedia@ieee.org
Phone: +1 212 419 7578 Email: hollandwfh@yahoo.com
Marion Delaney | IEEE Media, Advertising Director Fax: +1 212 419 7589 Japan
Phone: +1 415 863 4717 | Email: md.ieeemedia@ieee.org Email: j.restchack@ieee.org Midwest/Southwest (recruit- Tim Matteson
ment) Phone: +1 310 836 4064
Connecticut (product) Darcy Giovingo Fax: +1 310 836 4067
Marian Anderson | Advertising Coordinator Stan Greenfield Phone: +1 847 498-4520 Email: tm.ieeemedia@ieee.org
Phone: +1 714 821 8380 | Fax: +1 714 821 4010 Phone: +1 203 938 2418 Fax: +1 847 498-5911
Fax: +1 203 938 3211 Email: dg.ieeemedia@ieee.org Europe (product)
Email: manderson@computer.org Email: greenco@optonline.net Hilary Turnbull
Southwest (product) Phone: +44 1875 825700
Midwest (product) Steve Loerch Fax: +44 1875 825701
Sandy Brown Dave Jones Email:
Phone: +1 847 498 4520
IEEE Computer Society | Business Development Manager Phone: +1 708 442 5633 Fax: +1 847 498 5911 impress@impressmedia.com
Phone: +1 714 821 8380 | Fax: +1 714 821 4010 Fax: +1 708 442 7620 Email:
Email: dj.ieeemedia@ieee.org steve@didierandbroderick.com
Email: sb.ieeemedia@ieee.org Will Hamilton

Circulation: Computing in Science & Engineering (ISSN 1521-9615) is published bimonthly by the AIP and the IEEE Computer Society. IEEE Headquarters,
Three Park Ave., 17th Floor, New York, NY 10016-5997; IEEE Computer Society Publications Office, 10662 Los Vaqueros Circle, PO Box 3014, Los Alamitos,
CA 90720-1314, phone +1 714 821 8380; IEEE Computer Society Headquarters, 1730 Massachusetts Ave. NW, Washington, DC 20036-1903; AIP
Circulation and Fulfillment Department, 1NO1, 2 Huntington Quadrangle, Melville, NY 11747-4502. 2007 annual subscription rates: $45 for Computer
Society members (print plus online), $76 (sister society), and $100 (individual nonmember). For AIP society members, 2007 annual subscription rates are
$45 (print plus online). For more information on other subscription prices, see www.computer.org/subscribe/ or https://www.aip.org/forms/journal
_catalog/order_form_fs.html. Computer Society back issues cost $20 for members, $96 for nonmembers; AIP back issues cost $22 for members.
Postmaster: Send undelivered copies and address changes to Computing in Science & Engineering, 445 Hoes Ln., Piscataway, NJ 08855. Periodicals postage
paid at New York, NY, and at additional mailing offices. Canadian GST #125634188. Canada Post Corporation (Canadian distribution) publications mail
agreement number 40013885. Return undeliverable Canadian addresses to PO Box 122, Niagara Falls, ON L2E 6S8 Canada. Printed in the USA.
Copyright & reprint permission: Abstracting is permitted with credit to the source. Libraries are permitted to photocopy beyond the limits of US
copyright law for private use of patrons those articles that carry a code at the bottom of the first page, provided the per-copy fee indicated in the code is
paid through the Copyright Clearance Center, 222 Rosewood Dr., Danvers, MA 01923. For other copying, reprint, or republication permission, write to
Copyright and Permissions Dept., IEEE Publications Administration, 445 Hoes Ln., PO Box 1331, Piscataway, NJ 08855-1331. Copyright © 2007 by the
Institute of Electrical and Electronics Engineers Inc. All rights reserved.

that the Renderer instance has a draw lines method, but The requirement for high-quality 3D graphics and visual-
doesn’t know what kind of output it renders to, be it a Post- ization in Python is mostly solved via the wrapping of VTK;
Script canvas or GTK DrawingArea. Likewise, the renderer MayaVi2, which is part of the Enthought Toolsuite
and canvas don’t know anything about the matplotlib coordi- (http://code.enthought.com), provides a convenient Matlab-
nate system or figure hierarchy or primitive geometry types; like interface to VTK’s fairly complex functionality. Mat-
instead, they rely on the individual artists to do the layout and plotlib provides some rudimentary 3D graphics, and we want
transformation and make the appropriate primitive renderer to improve them so that our users can rely on basic function-
calls. Although this design isn’t always ideal—for example, it ality for surfaces, meshes, and 3D scatterplots without having
doesn’t exploit some of the features in a given output specifi- to depend on the VTK installation. But for anything more so-
cation—it does keep the back ends reasonably simple and phisticated, we prefer to stick to our core competency—high-
dumb, allowing us to quickly add support for a new format. quality interactive scientific 2D graphs—rather than trying to
replicate the already fantastic graphics provided by VTK and
the MayaVi wrappers.

M atplotlib has achieved many of its early goals; its cur-


rent objectives include improving performance for
real-time plotting and offering better support for an arbi- John D. Hunter is Senior Research Programmer and Analyst at
trary number of scales for a given axis, user coordinate sys- Tradelink. His research interests include scientific visualization and
tems, and basic 3D graphics (http://matplotlib.sf.net/goals. event-driven trading strategies. Hunter has a PhD in neurobiology
html). The latter goal is one of the most frequent requests from the University of Chicago. Contact him at jdh2358@
from matplotlib users. gmail.com.

MAY/JUNE 2007 95

You might also like