Monthly Archives: December 2012

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


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

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


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())

Update: Floating-point exception handling on Mac OS X

A few months ago, I was having a few problems porting some C++ code over to Mac OS X because of some non-standard floating-point exception handling functions that are present in glibc on Linux. Well, it just so happened that a colleague of mine, Rich Booth, recently ran into the same problem, only from a different angle. He wanted to keep track of floating point exceptions in a simulation code of his, but found that he couldn’t do this on his Mac.

After a bit of digging around, we found a portable implementation of floating point exception handling that would happily run on both Linux and Mac OS X. It was written by David N. Williams in 2009, and includes some good documentation on the implementation in the comments. There’s also an example program right at the end of the file, so you can test it out right away.

The code should be simple enough to figure out pretty quickly, but Rich split out a header file anyway, just to make everyone’s lives that bit easier. You can find a tarball with Rich’s modifications here.

Patrick Moore

Sir Patrick Moore passed away today, aged 89. Through his many, many books, and TV programmes like The Sky at Night, he became Britain’s foremost populariser of astronomy. It’s safe to say he’s inspired several generations of scientists, showing us the poignant beauty of the heavens and incredible excitement of space exploration, all in his own, unique way.

I have a particularly fond memory of him. When I was quite young, probably around 8 years old, my dad and uncle took me to see Patrick give a lecture at the Victoria Hall in Stoke. I seem to remember that much of it was about Mars, and how astronomers past had mistakenly seen canals and other marks of civilisation on its surface. I still have a copy of a little red book of his, “Into Space!”, lying around somewhere at home, that we bought on the night. We also took my copy of Philip’s Atlas of the Universe (another of his), which he graciously signed for me after the lecture. I can’t remember what he said to me, other than that he’d sprained his wrist, so could only manage to scrawl his initials on the first page! I recall being slightly put out by this, for some reason – perhaps because it looked like someone had randomly scrawled on the book, thus defacing it. (Anyone who knows me will have some appreciation of how cardinal a sin the defacement of a book, however slight, is in my eyes.)

Meeting Patrick was one of a number of important events in my development that happened at around the same time. My dad bought me a little black Tasco refractor, and managed to get a stunning view of Jupiter out of it, one that I couldn’t reproduce myself for many years. A couple of years earlier, he’d woken me up in the middle of the night, literally carrying me out of bed to see a lunar eclipse. My parents had also been indulging me by buying science books, which I absolutely lapped up. One of these was Patrick’s Atlas of the Universe, the one he signed, which I often dipped into. In 1999, there was also a solar eclipse in Britain, only partial in Stoke but reaching totality in Cornwall, which I remember Patrick doing the commentary for.

These events, along with many others of a similar nature over the years, have shaped me both intellectually and personally. Being an astrophysicist is a big part of who I am, and I’m forever grateful to all of the people like Patrick who set me out on this path all those years ago. I only hope I can repay the debt by inspiring others myself.