Menu
Cart

Replicating 538's plot styles in Matplotlib

Posted by Cameron Davidson-Pilon at

Nate Silver's FiveThirtyEight site has some aesthetically pleasing figures, ignoring the content of the plots for a moment:

After pulling a few graphs locally, sampling colors, and crowd-sourcing the fonts used, I was able to come pretty close to replicating the style in Matplotlib styles. Here's an example (my figure dropped into an article on FiveThirtyEight.com)

Another example using the replicated styles:

So how to do it?

[Edit: these steps are old, you can still use them, but there is a better solution in the Update below]. I've prepacked the styles in a json file, located in this gist. Saving that file locally, you can use the following code to load it temporarily into your matplotlib styles: code here.

Notable Departures

  • The font they use for their axes is Decima Mono, a paywalled font, and there are no available alternatives.
  • They often have healthy margins between the lines and the axes, I wasn't able to replicate this.
  • Their figures almost always have a title and subtitle of different weights.

Conclusion

I'm not sure what software the team at FiveThirtyEight uses (Excel, Stata?), but there is definitely some post-processing of whatever the software spits out. The same can be done here, in which case you could achieve complete replication.

Update

Here's an R version that @AustinClemens2 worked out.

New way: Matplotlib 1.4 now handles changing styles really well, using the plt.style.use('ggplot') syntax. (See full instructions here). I submitted a PR to have FiveThirtyEight style included in Matplotlib, so now you can type plt.style.use('fivethirtyeight')! I also include the popular Bayesian Methods for Hackers color scheme, plt.style.use('bmh'). Give it a try!

 

Related Posts


Latest Data Science screencasts available


  • Hi Cameron, thank you for this post and also for the PR to add the ‘fivethirtyeight’ style.

    I just wanted to leave a note to other users new to applying styles:
    Make sure you call style.use() before plot(), otherwise the styles won’t apply.
    E.g.

    plt.style.use(‘fivethirtyeight’)
    plt.plot(x, y)

    This might be trivial to experienced users, but I had a hard time figuring out.

    Imre on
  • Cool! Both of your plots have the labels in the lower-left corner way too close to each other, though. This seems to be a general problem in Matplotlib. Is there a good way to fix it?

    Petter on
  • This is very cool! Thanks for taking the time to write it. :)

    Kostis on

Leave a comment

Please note: comments will be approved before they are published