10 Sep 2017

Sane Date Axes in Matplotlib

Timeseries graphs are commonplace, but there doesn’t seem to be a sane way to plot date axes in Matplotlib (and I’m not the only one who thinks so). This is what the default plot produces:

One solution is to rotate the labels, but reading the slanted wording isn’t easy, and it’s not immediately clear where the labels line up.

Pandas’ solution is slightly better. Organizing the various time periods (eg. days, months, years) into layers helps readability and makes it each label shorter so no rotation is needed. However, it is inconvenient to have to convert data into Pandas dataframes just to use the plotting functionality. One other shortcoming is that the reader has to work hard to deduce the month of the first few ticks.

We now have a sense of what a good solution should look like:



Solution

I implemented nice_dates() which infers the density and type of ticks to display based on the width of the plot. It organizes the labels based on the hierarchy of time periods while always contextualizing the first data point with two extra levels of time periods. It supports time intervals from 1 second to 10 years, but can be easily extended.

Source