Menu

[r8989]: / trunk / py4science / workbook / matplotlib_tut.tex  Maximize  Restore  History

Download this file

512 lines (380 with data), 20.5 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
\chapter[matplotlib]{Introduction to plotting with matplotlib / pylab}
\section[Overview]{A bird's eye view}
matplotlib is a library for making 2D plots of arrays in python.%
\footnote{This short guide is not meant as a complete guide or tutorial. There
is a more comprehensive user's guide and tutorial on the matplotlib web-site
at http://matplotlib.sf.net.%
} Although it has its origins in emulating the Matlab graphics commands, it
does not require matlab, and has a pure, object oriented API. Although
matplotlib is written primarily in 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 on; it should just work.
The matplotlib code is divided into three parts: the \textit{pylab
interface} is the set of functions provided by the \texttt{pylab}
module which allow the user to create plots with code quite similar
to matlab figure generating code. The 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 knowns nothing about output formats. 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, GTK embeds matplotlib in a GTK
application, GTKAgg uses the antigrain%
\footnote{http://antigrain.com%
} renderer to create a figure and embed it a GTK application, and so
on for WX, Tkinter, FLTK, \ldots{}.
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, which
is discussed at length below 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 \LaTeX{} documents and publication
quality printing
\item Embeddable in a graphical user interface for application development
\item The code should be mostly python so itis easy to understand and extend
-- users become developers!
\item Making plots should be easy -- just a few lines of code for simple
graphs
\end{itemize}
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.
Without further ado, let's create our first figure. This example uses
the matplotlib object oriented API. Most users use the pylab interface,
which will be discussed next and makes it easier to make plots because
a lot of the tedius work of creating and managing figures and figure
windows is done for you behind the hood. But since the real core of
the library is the object oriented API, I think it is a good place
to start. If you are developing a graphical user interface or making
plots on a web server, you probably want maximal control with no magic
going on behind the scenes -- this is where the matplotlib API should
be used. If you are just trying to make a figure for inclusion in
a paper or if your working interactively from the python shell, you'll
probably be happy with the pylab interface.
\lstinputlisting[caption={Creating a simple figure with the antigrain backend (generates PNG) using the object oriented matplotlib library}]{examples/mpl_agg_oo.py}
%
\begin{figure}
\begin{centering}
\includegraphics[width=4in]{fig/mpl_one_two_three}
\par\end{centering}
\caption{\label{fig:mpl_agg}A simple plot generated by the antigrain (Agg)
backend .}
\end{figure}
\section[pylab tutorial]{A short pylab tutorial}
Here is about the simplest code you can use to create a figure with
matplotlib using the pylab interface. In this section, I'm assuming
you are using ipython in the pylab mode -- see Section\ref{sec:ipython_pylab}
for details.
\begin{lyxcode}
peds-pc311:\textasciitilde{}>~pylab
Python~2.3.3~(\#2,~Apr~13~2004,~17:41:29)
Type~\char`\"{}copyright\char`\"{},~\char`\"{}credits\char`\"{}~or~\char`\"{}license\char`\"{}~for~more~information.
~
IPython~0.6.12\_cvs~-{}-~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(pylab)~~~~~~->~matlab-compatible~commands~from~matplotlib
~~~~help(plotting)~~~->~plotting~commands
~
In~{[}1]:~plot({[}1,2,3])
Out{[}1]:~{[}<matplotlib.lines.Line2D~instance~at~0xb557a86c>]
\end{lyxcode}
%
\begin{figure}
\begin{centering}
\includegraphics[width=5in]{fig/mpl_toolbar}
\par\end{centering}
\caption{\label{fig:mpl_toolbar}The matplotlib toolbar used to navigate around
your figure}
\end{figure}
If your settings are correct, a figure window should popup and you
should be able to interact with it. That's a lot less typing than
our initial example using the object oriented API in which you had
to manually create the Figure, Axes and so on!
Try clicking on the navigation toolbar at the bottom of the figure
-- the toolbar is shown in Figure\ref{fig:mpl_toolbar}. The first
three buttons from left to right in Figure\ref{fig:mpl_toolbar} are
\textit{home}, \textit{back} and \textit{forward}. These byttons are
are akin to the web browser 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
as described below. This is analogous to trying to click \texttt{Back}
on your web browser before visiting a new page --nothing happens.
The home button always takes you to the first, default view of your
data.
The next to button moving right is the pan/zoom button, which looks
like a cross with arrows on the end (a \textit{fleur}). The pan/zoom
button button has two modes: pan and zoom (no surprise there, right?).
Click this toolbar button to activate this mode; you should see {}``pan/zoom
mode'' show up in the status bar. Then put your mouse somewhere over
an axes. To activate panning: press the left mouse button and hold
it, dragging it to a new position. If you press \texttt{x} or \texttt{y}
while panning, the motion will be contrained to the x or y axis, respectively
. To activate zooming, 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 remains stationary, allowing you to zoom to
an arbitrary point in the figure. You can use the modifier keys \texttt{x},
\texttt{y} or \texttt{CONTROL} to constrain the zoom to the x axes,
the y axes, or aspect ratio preserve, respectively.
The next button moving right is the \textit{zoom to rectangle button}
which has a magnifying glass over a piece of paper. The button is
striaghtforward and works in the standard way; when you click it,
you should see that it is activated by looking for {}``Zoom to rect
mode'' in the status bar, and then you select the rectangular region
you want to zoom in on.
The final button is the \textit{save button}, which will save your
figure in the current view. All of the {*}Agg backends know how to
save the following image types: PNG, PS, EPS, SVG.
Let's make the same figure we made using the object oriented API above,
ie Figure\ref{fig:mpl_agg}, but this time using the pylab\lstinputlisting[caption={Creating a simple figure in pylab}]{examples/mpl_pylab.py}
As you can see there is basically a direct translation between the
OO interface and the pylab interface. When \texttt{plot} is called,
the pylab interface makes a call to the function \texttt{gca()} (``get
current axes'') to get a reference to the current axes. \texttt{gca}
in turn, makes a call to \texttt{gcf} ({}``get current figure'')
to get a reference to the current figure. \texttt{gcf}, finding that
no figure has been created, creates the default figure using \texttt{figure()}
and returns it. \texttt{gca} will then return the current axes of
that figure if it exists, or create the default axes \texttt{subplot(111)}
if it does not. The last line show is a GUI independent way of actually
creating a figure window, and is not required for image backends such
as postscript.
Thus a lot happens under the hood when you call plot, but for the
most part you don't need to think about it -- it just works. The important
thing to understand is that the pylab interface has a state, and keeps
track of the current figure and axes. All plotting commands target
the current axes, and you can manipulate which ones are current
\lstinputlisting[caption={Creating multiple subplots and plotting multiple lines in a single plot command}]{examples/mpl_subplot_demo.py}
%
\begin{figure}
\begin{centering}
\includegraphics[width=4in]{fig/mpl_subplot_demo}
\par\end{centering}
\caption{\label{fig:mpl_subplot}It's easy to create multiple axes and subplots.}
\end{figure}
In addition to creating multiple subplots, this example contains a
couple of new things. In the first plot command, the return value
is stored as \texttt{l1, l2} and the \texttt{set} command is used
to change a default line property.
\begin{lyxcode}
l1,~l2~=~plot(t1,~f(t1),~'bo',~t2,~f(t2),~'k-{}-')
set(l1,~markerfacecolor='g')
\end{lyxcode}
\texttt{l1} and \texttt{l2} are \texttt{matplotlib.lines.Line2D} instances
and they are created by the \texttt{plot} command and added to the
current axes. This is the typical mode of operation of the axes plot
commands: they create a bunch of primitive objects (lines, polygons,
text, images), add them to the axes, and return them. In this example,
the line's \texttt{markerfacecolor} property is set with the \texttt{set}
command. In the next section, we'll look into matplotlibs \texttt{set}
and \texttt{get} introspection system and show how to use it to customize
your lines, polygons, text instances and images.
\section[set and get]{Set and get introspection}
Everything that goes into a matplotlib figure, including the \texttt{Figure}
itself, are all objects dervied from a single base class \texttt{Artist,}
and the pylab \texttt{set} and \texttt{get} commands provide a unified
way to configure them. Let's create a simple plot of random circles,
and use that to explore how \texttt{set} and get work. First the basic
plot -- we'll store the return value as lines. Note that \texttt{plot}
always returns a \textit{list} of lines; in the example above there
were two lines \texttt{l1} and \texttt{l2}, and in the example below
there is only a single element of the list lines. No matter: \texttt{set}
and \texttt{get} will work on a single instance or a sequence of instances
\lstinputlisting{snippets/mpl_plot_line.ipy}
%
\begin{figure}
\begin{centering}
\includegraphics[width=4in]{fig/mpl_set_get1}
\par\end{centering}
\caption{\label{fig:mpl_setget1}The default marker plot, before marker customization}
\end{figure}
The simple figure that was created, a scattering of blue circles at
random locations, is shown in Figure\ref{fig:mpl_setget1}. To see
a listing of the properties of the line, and what their current values
are, call \texttt{get(lines)} \lstinputlisting{snippets/mpl_get.ipy}
and to see the same listing of properties with information on legal
values you can set them to, call \texttt{set(lines)}\lstinputlisting{snippets/mpl_set.ipy}
OK, we have a lot of options here. Let's change the marker properties,
and add a linesytle
\begin{lyxcode}
In~{[}20]:~set(lines,~markerfacecolor='green',~markeredgecolor='red',
~~~....:~~markersize=20,~markeredgewidth=3,~
~~~....:~linestyle='-{}-',~linewidth=3)
\end{lyxcode}
That's a lot of typing, but to great effect! The same data set now
has quite a different appearance, which is shown in Figure\ref{fig:mpl_setget2}.
Note in the long listing output of the set(lines) command above the
markerfacecolor settable property is listed as
\begin{lyxcode}
markerfacecolor~or~mfc:~any~matplotlib~color~-~see~help(colors)
\end{lyxcode}
The \texttt{markerfacecolor} has an alias \texttt{mfc} to save typing,
and common colornames have abbreviations too, so the \texttt{set}
command above could just as well be written
\begin{lyxcode}
In~{[}20]:~set(lines,~mfc='g',~mec='r',~ms=20,~mew=3,~ls='-{}-',~lw=3)
%
\begin{figure}
\begin{centering}
\includegraphics[width=4in]{fig/mpl_set_get2}
\par\end{centering}
\caption{\label{fig:mpl_setget2}The default marker plot, before marker customization}
\end{figure}
\end{lyxcode}
Another nice thing about matplotlib properties is that you can pass
them in as keyword arguments to \texttt{plot} and they will have the
same effect, eg, you can create the identical plot with
\begin{lyxcode}
In~{[}6]:~plot(x,~y,~'o',~mfc='g',~mec='r',~ms=20,~mew=3,~ls='-{}-',~lw=3)
Out{[}6]:~{[}<matplotlib.lines.Line2D~instance~at~0xb40db42c>]
\end{lyxcode}
As noted above, \texttt{set} and \texttt{get} work on any \texttt{Artist},
so you can configure your axes or text instances this way. Eg, \texttt{xlabel}
returns a \texttt{matplotlib.text.Text} instance \lstinputlisting{snippets/mpl_text_set.ipy}
\begin{lyxcode}
\end{lyxcode}
So you have a lot of possibilities to customize your text! The most
common things people what to do are change the font size and color;
the results of this command on the xlabel are shown in Figure\ref{fig:mpl_setget2}.
\begin{lyxcode}
In~{[}25]:~set(t,~fontsize=20,~color='darkslategray')~
\end{lyxcode}
\section[matplotlibrc]{Customizing the default behavior with the rc file}
matplotlib is designed to work in a variety of settings: some people
use it in \char`\"{}batch mode\char`\"{} on a web server to create
images they never look at. Others use graphical user interfaces (GUIs)
to interact with their plots. Thus you must customize matplotlib to
work like you want it to with the customization file \texttt{.matplotlibrc},
in which you can set whether you want to just create images or use
a GUI (the backend setting), and whether you want to work interactively
from the shell (the interactive setting). Almost all of the matplotlib
settings and figure properties can be customized with this file, which
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 \texttt{setup.py} and will be copied
into your install path. Typical locations for this file are
\begin{lyxcode}
C:\textbackslash{}Python23\textbackslash{}share\textbackslash{}matplotlib\textbackslash{}.matplotlibrc~\textcolor{blue}{\#~windows}~/usr/share/matplotlib/.matplotlibrc~~\textcolor{blue}{\#~linux}
\end{lyxcode}
By default, the installer will overwrite the existing file in the install path,
so if you want to preserve yours, please move it to your \texttt{HOME} dir and
set the environment variable if necessary. In the rc file, you can set your
backend, whether you'll be working interactively and default values for most of
the figure properties.
In the RC file, blank lines, or lines starting with a comment symbol,
are ignored, as are trailing comments. Other lines must have the format
\begin{lyxcode}
~key~:~val~\textcolor{blue}{\#~optional~comment}~
\end{lyxcode}
where \textit{key} is some property like \texttt{backend}, \texttt{lines.linewidth},
or \texttt{figure.figsize} and \textit{val} is the value of that property.
Example entries for these properties are
\begin{lyxcode}
\textcolor{blue}{\#~this~is~a~comment~and~is~ignored~}
backend~~~~~~~~~:~GTKAgg~~~~\textcolor{blue}{\#~the~default~backend~}
lines.linewidth~:~0.5~~~~~~~\textcolor{blue}{\#~line~width~in~points}~
figure.figsize~~:~8,~6~~~~~~\textcolor{blue}{\#~figure~size~in~inches~}
\end{lyxcode}
A complete sample rc file is included with the matplotlib distribution
and available online.%
\footnote{http://matplotlib.sourceforge.net/.matplotlibrc%
}
\section[Plot Types]{A quick tour of plot types}
\section{Images}
Matplotlib has support for plotting images with imshow and figimage.
In imshow, the image data is scaled to fit into the current axes,
and many different interpolation schemes are supported to do the resampling,
and in figimage, the image data are transferred as a raw pixel dump
to the figure canvas without resampling. You can add colorbars, set
the default colormaps, and change the interpolation schemes quite
easily.
%
\begin{figure}
\begin{centering}
\includegraphics[width=4in]{fig/mpl_image_jet}
\par\end{centering}
\caption{\label{fig:mpl_imshow_jet}A simple image plot of a 2D matrix, using
nearest neighbor interpolation and the \texttt{jet} colormap.}
\end{figure}
\begin{lyxcode}
In~{[}15]:~x~=~arange(100.0);~x.shape~=~10,10
~
In~{[}16]:~im~=~imshow(x,~interpolation='nearest')
~
In~{[}17]:~colorbar()
Out{[}17]:~<matplotlib.axes.Axes~instance~at~0xb455496c>
\end{lyxcode}
which creates the image shown in Figure \ref{fig:mpl_imshow_jet}.
You can interactively update the default colormap and change the
interpolation scheme, which creates the image show in Figure \ref{fig:mpl_imshow_hot}.
\begin{lyxcode}
In~{[}18]:~im.set\_interpolation('bilinear')
~
In~{[}19]:~hot()
%
\begin{figure}
\begin{centering}
\includegraphics[width=4in]{fig/mpl_image_hot}
\par\end{centering}
\caption{\label{fig:mpl_imshow_hot}The same image data, rendered with the
hot colormap and bilinear interpolation. matplotlib has 14 colormaps
built-in, and you can define your own with relative ease, and there
are 16 interpolation methods.}
\end{figure}
\end{lyxcode}
There is a lot more you can do with images: you can set the data extent
so that you can overlay contours or other plots, you can plot multiple
images to the same axes with different colors and transparency values,
you can load images with PIL or \texttt{imread} and plot them in matplotlib,
you can create montages of with \texttt{figimage} placed around the
figure window at different offsets, you can plot grayscale, rgb or
rgba data, and so on. Consult the \textit{Matplotlib User's Guide}
and the \texttt{examples} subdirectory in the matplotlib source distribution
for more information. We'll clost off with a simple example of reading
in a PNG and displaying it
\begin{lyxcode}
In~{[}35]:~im~=~imread('../data/ratner.png')
~
In~{[}36]:~imshow(im)
Out{[}36]:~<matplotlib.image.AxesImage~instance~at~0xb3ffba2c>
~
In~{[}37]:~axis('off')
%
\begin{figure}
\begin{centering}
\includegraphics[width=5in]{fig/mpl_ratner}
\par\end{centering}
\caption{\label{fig:mpl_ratner}Displaying image data from your camera in matplotlib}
\end{figure}
\end{lyxcode}
\section[Text]{Customizing text and mathematical expressions}
\section[Event]{Event handling: Tracking the mouse and keyboard}
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.