add_subplot only really uses those numbers to calculate position and size so each call is unrelated to others, and mixing grid sizes will make a mess

Keep in mind that the object representing a subplot is Axes and so many examples call their subplots 'axis' or such.

It may be better for you to call them plot or such, in that it can gets confusing that an Axes named axis has an Axis (the last as in the label-and-tick thing)

Spanning cells

A few ways (one alternative is subplot2grid()), I prefer the following :

# you may want to see the result before you try to read the coords# basically settles the overall granularity of...
ax1 = fig.add_subplot( gs[0, : ])# first row, all columns
ax2 = fig.add_subplot( gs[1, 0:2])# second row, left and middle cells
ax3 = fig.add_subplot( gs[1:, 2])# second and third row, last-column
ax4 = fig.add_subplot( gs[2, 0])# last row, first column
ax5 = fig.add_subplot( gs[2, 1])# last row, second column
plt.show()

Note that this positions the part of the plot that data is drawn in, and ignores the axis labels, titles, etc.
If you care about that, look at tight_layout

tight_layout

The default is nicely spacious, but sometimes (e.g. when producing images) you don't want wasted space.

fig.tight_layout()

alters the positions of axes's contents to remove most whitespace (note: looks at ticklabels, axis labels, and titles - does not measure anything else that may be present outside the plot area)

It's experimental -- and apparently will stay so. Sometimes it's very handy, but try not to rely on it.

Various backends lack a direct implementation, which is why if you ask for it you may see:

tight_layout : falling back to Agg renderer

this seems to mean matplotlib is redoing the plot in Agg renderer to calculate the new positions (it needs to call get_renderer(), which not all backends provide), then and does the setting and drawing in your requested backend(verify).
So you can ignore the warning if you don't care about the extra work(verify)

Boxes around text happen when you specify bbox. The value to bbox is a dict that specifies how to draw it, a dict including things like:

boxstyle:"rarrow,pad=0.3"

fc:"cyan"

ec:"b"

lw:2

Note that one alternative is instantiating AnchoredText, which is how legends are made. You can get anchored things more generic than that.

Arrows (other than a bbox with larrow/rarrow/darrow for its shape) happen when you have an xy and an xytext: an arrow will be drawn from the latter to the former (and the text that is the first, non-keyword argument will also be drawn at the latter).

figure out start and end indices in the data, and do a series of plot() calls, like:

plot(x[start:end], y[start:end], lw=2, c=segment_color[i])

numpy mask arrays, separate plot() calls

more readable if it's a single split based on x or y value.

The below example is for two segments. You'ld need to generalize it to be more flexibe

span style="color: #a05050; font-style: italic;"># note: won't work when they're python arrays
'data (avrot)''''Overall, and per type of thing'''"python">
ourfontsize = 10
matplotlib.pyplot.rcParams["font.size"] = ourfontsize
# The following are by default relative to font.size, but can be set to a fixed size
matplotlib.pyplot.rcParams['axes.titlesize'] = 'large'
matplotlib.pyplot.rcParams['axes.labelsize'] = 'medium'
matplotlib.pyplot.rcParams['figure.titlesize'] = 'medium'
matplotlib.pyplot.rcParams['legend.fontsize'] = 'large'
matplotlib.pyplot.rcParams['xtick.labelsize'] = 0.6*ourfontsize # if you want more control
matplotlib.pyplot.rcParams['ytick.labelsize'] = 0.6*ourfontsize
# (the last because you cannot hand in a scale, only a specific size)

Blocking and non-blocking plot windows

The sensible cases

within a notebook means from then on it will pick up on created plot objects, and render them as an inline image (static image in interactive context)

To get interaction with the plot, use:

%matplotlib nbagg

(ipython 2)

%matplotlib notebook

(since ipython 3)

From an interactive python prompt

Use ipython rather than plain python.

After a

%matplotlib

[4] it will notice when you produce a figure object(verify) and fires off a window for it. (Without an argument to the magic function it will choose a GUI backend for you. You can specify a specific one if you want.)

from one-off CLI scripts

If you have a script in the "gather data, show the results, done" style,
then it is actually useful to block program flow while the plots are shown.
(in that it means you don't have to ensure some sort of threading, only to have to listen for the figure close to postpone the program's exit)

...which is more or less the default when you use

pyplot.show()

with non-embedded interactive GUI backends: They'll create their own window with their own event loop, which is the thing that blocks until the plot window(s) it created are closed.

Plots with their own interaction

Everything you want to happen can be hooked into interactive events (or a timer), and thereby just the figure's mainloop.

The interesting cases

I frequently write a script that gathers some data, shows it, and updates it later (Be it iterations done within the same program, or watching files, a database, or whatnot)

This means a few different details

leaving the originating program interactive

leaving the plot window interactive

ensuring draws-to-screen happen

having the originating program wait for the window to close before quitting itself

The exact solution depends on what exactly you are doing. (TODO: examples)

Interactive mode is a good part of the answer (but also a bit confusing, details vary a bit with backend, and parts are a bit experimental). Interactive mode refer more to how it leaves your shell than to the plot itself.(verify)

Use of an interactive backend (see What is a backend?)
permits–but does not by itself require or ensure–plotting to the screen.
Whether and when plotting to the screen occurs, and whether a script or shell session
continues after a plot is drawn on the screen, depends on the functions and methods that are called,
and on a state variable that determines whether matplotlib is in “interactive mode”.
The default Boolean value is set by the matplotlibrc file, and may be customized
like any other configuration parameter (see Customizing matplotlib).
It may also be set via matplotlib.interactive(), and its value may be
queried via matplotlib.is_interactive().

pyplot.pause:

If there is an active figure it will be updated and displayed,
and the GUI event loop will run during the pause.
If there is no active figure, or if a non-interactive backend
is in use, this executes time.sleep(interval).
This can be used for crude animation.

Notes so far:

setting interactive mode:

matplotlib.interactive(True)

and/or

pyplot.ion()

matplotlib.interactive(False)

and/or

pyplot.ioff()

toggling it in the middle of your program is probably more confusing than useful

in interactive mode, OO-style (or altering plot state manually) will not imply a draw() (pylab-style calls still do)

Gui shells are at best problematic, because they have to run a mainloop,
but interactive plotting also involves a mainloop.
Ipython has sorted all this out for the primary matplotlib backends.
There may be other shells and IDEs that also work with matplotlib in interactive mode,
but one obvious candidate does not: the python IDLE IDE is a Tkinter gui app
that does not support pylab interactive mode, regardless of backend.

matplotlib in browsers

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

mpld3 notes

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

Digging deeper, necessary hacks, lower level notes, etc.

Dates

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

The easiest way to deal with dates is to hand in datetime objects.

Matplotlib will do everything for you, primarily choosing an appropriate axis ticker formatter (AutoDateFormatter) (also convert the dates to its interal format).

When you want more manual or lower-level control (e.g. update the plot via set_data), then you probably have to deal with its internal format, possibly set a AutoDateFormatter yourself.

(You can hand in numbers representing dates and e.g. use plot_date() over plot(), but there are no such alternatives for various other plot functions.)

Running from minimal environments (like a web server)

To run without X, choose a backend that uses it, before a call that implicitly chooses a backend for you (pylab, also pyplot).

Choices include Cairo (usually looks nicest), Agg, or things like ps or pdf, and more. For example:

span style="color: #483d9b;">'Cairo')

matplotlib wants a HOME directory, and it should be writeable.
This usually only matters when embedding in web environments (apache, mod_wsgi, CGI) where HOME is typically not set.
You should alter this before you import matplotlib, like:

Writing to images (memory-only)

Cairo

Which is easy, and more memory-efficient than going via an additional uncompressed raster.

By default it writes PNGs, and you can make it write other formats by handing along a format parameter to savefig, such as savefig(sio,format='PNG'), or one of 'PDF', 'PS', 'EPS', 'SVG'.

For example, we might wrap our plot-generating code like:

span style="color: #a05050; font-style: italic;"># plot code
'PNG'

Agg

You can ask Agg's figure/canvas for RGB pixel data (note: easily large).
Can be useful when you want to send it straight to PIL.

#If you do things at the figure level (i.e. pylab), get the underlying canvas, # and make sure the figure is drawn on the canvas (you may well get an empty image if it isn't)# Get the canvas' pixel size as a (x,y) tuple; you'll need to hand this to PIL along with the raw data.# (You could probably do this at canvas level, but I prefer to use the underlying renderer so that you don't have to remember the dpi)# apparently this became floats at some point, # which the below does not like.# Export raw image (also possible at canvas level) # then e.g. read it into a PIL image. 'RGB'# You can use transparency, but ARGB is larger and takes a little more code to explain to PIL#Make PIL save the image and store it into a string:
im.save(pngdata, 'PNG')

Producing raster images for web use may be easiest with Cairo, because:

It allows StringIO-based saving, which most others do not

You do not have to switch backends to produce PNG, PDF, EPS, SVG -- which is useful because you cannot switch backends (an imposed restioction because not all backends react well to this) when you use persisting interpreters, which might apply to WSGI, mod_python and more.