Customising contour plots in matplotlib

So, you need to include a contour plot in some publication of yours, little one? There are two things that you must learn. But beware! The first will raise your spirits, while the second will quicken your descent into madness. These facts I address to you, should you stand to read them: (1) matplotlib has a really customisable contour plot implementation; (2) the convenience functions are few, and the necessary keyword arguments are confusing.

I’m prepping a bunch of contour plots for a publication in a quick letter at the moment, and want to improve their legibility. This involves things like making all of the lines thicker, increasing the font size of the labels (both on the axes and on the contours themselves), and changing the contour scaling. Some of these modifications have proven more difficult than others with matplotlib, so I thought I’d jot down a couple of examples here for reference. (The matplotlib contour examples are useful, but don’t cover everything.)

Tick size

First of all, let’s change the width and length of the ticks on each axis, and the size of the font of the labels for each tick.

import pylab as P

MP_LINEWIDTH = 2.4
MP_TICKSIZE = 10.

P.rc('axes', linewidth=MP_LINEWIDTH)

P.subplot(111)
for tick in P.gca().xaxis.get_major_ticks():

  tick.label1.set_fontsize(20.)
  tick.tick1line.set_markeredgewidth(MP_LINEWIDTH)
  tick.tick2line.set_markeredgewidth(MP_LINEWIDTH)
  tick.tick1line.set_markersize(0.5*MP_TICKSIZE)
  tick.tick2line.set_markersize(0.5*MP_TICKSIZE)

The call to P.rc() changes the thickness of all of the axis lines on the plot (i.e. it changes the global properties, and isn’t restricted to just one plot). The other stuff could probably be done using calls to rc(), but that’s an exercise for another time.

Plot of Compton y-distortion.

An example of a customised contour plot in matplotlib.

The loop is over all major ticks on the x axis of the current subplot. (The call to gca() gets the current set of plot axes, but of course you could use the xaxis.get_minor_ticks() method from any previously-defined axes object.) The object tick1line is the x-axis at the bottom of the plot, and tick2line is at the top.

Inside the loop, I’m setting the font size of the tick label (the number that appears below each tick), the width of the tick (using the markeredgewidth property), and the length of the tick (using markersize). You can also do things like hiding certain ticks, hiding certain labels (especially useful if you want to remove the tick label at the origin, because it overlaps with the label for the other axis there), changing the appearance of gridlines (somewhat unintuitively), and so on. There’s a list of all the tick-related objects that you can change here.

This will only change the tick styles for the minor ticks on the x axis. To cover all of the ticks on the plot, you’ll need to loop through all the minor ticks using P.gca().xaxis.get_minor_ticks() too, and then do both major and minor ticks for the y axis (using P.gca().yaxis) as well.

Changing which values contours are drawn at, and how they are labeled

To change where the contours are drawn, you need to change the contour locator. This is a keyword argument to contour(), and requires a ticker object. There’s a list of built-in tickers here. In the example below, I wanted a log scaling for my plots, so I used LogLocator().

It’s also useful to be able to change the labels that are added to the contours.For this, you need to use the clabel() function (which controls contour labels) and manipulate the formatter, using the fmt keyword. A list of formatters is given here, with more documentation on them (including formatter-specific keyword arguments for further customisation) given further down that page. Particularly useful formatters include:

  • LogFormatterMathtext (which add LaTeX mathmode labels, especially useful for numbers with exponents)
  • FormatStrFormatter (which lets you use a C-like format string to determine how significant figures, signs, etc. are displayed)
  • FuncFormatter (which lets you define a custom function to handle string formatting)

Setting the font size of the contour label is as easy as changing the fontsize keyword of clabel().

Finally, a subtlety of contour() is its use of the linewidths keyword, rather than linewidth (as with other pylab functions). It works exactly the same otherwise.

from matplotlib import ticker
ctr = P.contour(X, Y, Z, locator=ticker.LogLocator(), colors='k', linewidths=3.0)
P.clabel(ctr, inline=1, fontsize=20., fmt=ticker.LogFormatterMathtext())

About Phil Bull

I'm a theoretical cosmologist, currently working as a NASA NPP fellow at JPL/Caltech in Pasadena, CA. My research focuses on the effects of inhomogeneities on the evolution of the Universe and how we measure it. I'm also keen on stochastic processes, scientific computing, the philosophy of science, and open source stuff. View all posts by Phil Bull

2 responses to “Customising contour plots in matplotlib

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: