Multiple lines, legends, datetime

If we draw multiple datasets and give them each a label,

ax.plot(..., label="mylabel")

then it's easy to create a legend out of these labelled items: simply call

ax.legend()

I prefer to position my legend outside the Axes, using

ax.legend(loc='center left',  bbox_to_anchor=(1.05,0.5), edgecolor='none')
fig.set_tight_layout(True)

Dates and times. Matplotlib understands datetimes. In this code, the datetime column is a string (that's what read_csv gives us), so we first convert it into a datetime objects that pandas and matplotlib can work with.

Histogram, line annotations, text annotation

Histogram.

ax.hist(VALUES, bins=INT)

Line annotations. To draw a straight horizontal or vertical line or range,

ax.axhline(y)
ax.axhspan(ymin, ymax)
ax.axvline(x)
ax.axvspan(xmin, xmax)

For sloped lines, I think it's simplest to create a dummy dataframe with a row for the start and a row for the end, and just use ax.plot.

Text annotation.

ax.text(x, y, TEXT)

This is different to the standard data-plotting command, like ax.scatter, in that x and y and TEXT MUST NOT be vectors.

To control the alignment of the text with respect to the x and y coordinates, use e.g. ha='left', va='top'.

Scatter plot, colour scale

Matplotlib has several built-in https://matplotlib.org/stable/tutorials/colors/colormaps.html.

Choose a colour scale with either of

cmap = plt.get_cmap('SCALENAME')
cmap = plt.get_cmap('SCALENAME', n)

In the first case, cmap is a function from $[0,1]$ to colours. In the second case, it maps $\{0,1,…,n-1\}$ to colours.

The code on the right plots stop-and-search incidents, colour-coded by police force. It uses the discrete colour scale 'Set2' (which only has eight distinct colours, so some forces share the same colour). The scatter plot shows us roughly an outline of England and Wales, colour-coded by region.

We can also achieve the same outcome without using a ‘for’ loop, by calling ax.scatter once and passing in the c argument,

ax.scatter(, c=COLOURLIST)

Heatmap, colour bar

To plot a heatmap, in other words to plot an array of values using coloured rectangles for each cell,

ax.imshow(ARRAY, 
    origin='lower', 
    extent=(LEFT,RIGHT,BOTTOM,TOP),
    cmap='COLSCALE', vmin=LO, vmax=HI)

This draws the array inside the rectangle specified by extent, with ARRAY[0,0] in the bottom left. The values are coloured with the specified https://matplotlib.org/stable/tutorials/colors/colormaps.html, with the colour scale running from LO to HI.

To add a legend for the colour scale,

plt.colorbar(im, ax)

where im is the return value from imshow, and where ax is the Axes or list of Axes from which to steal space to squeeze in the legend.

Subplots not in a grid; subplot spacing

For an array of subplots, use plt.subplots(nrows,ncols). For ‘wrapped’ subplots, use

fig = plt.figure()
ax1 = fig.add_subplot(nrows, ncols, index=1)
ax2 = fig.add_subplot(nrows, ncols, index=2)
...

We still have to say what the total size of the grid will be (so it knows how big to make each plot), but it only generates the subplots in that grid that we ask for.

We can adjust subplot spacing with

fig.subplots_adjust(wspace, hspace)

The plot below shows a histogram showing the typical number of stops on a Monday, and on a Tuesday, and so on.