When building small multiples plots (i.e. figures with > 1 rows and/or columns), I frequently find myself writing something like:
ncols = 3 nrows = int(np.ceil(len(my_list) / ncols)) ax_width, ax_height = 3, 2 fig, axes = plt.subplots( ncols=ncols, nrows=nrows, figsize=(ax_width * ncols, ax_height * nrows) )
It seems I’m not alone–searching on github there are lots of results for e.g. “nrows = int(np.ceil(”:
|Search Term||Python #||Jupyter #|
|“nrows = int(np.ceil(”||2,536||446|
|“ncols = int(np.ceil(”||1,090||123|
|“nrows = int(math.ceil(”||367||41|
|“ncols = int(math.ceil(”||190||10|
What do people think about adding one or both of the following arguments to e.g.
plt.subplots (which filter down to
GridSpec in turn):
naxesto handle the number of required axes
axsizeto determine the required
I think (1) is more useful and probably easier to implement than (2); you could call e.g.:
fig, axes = plt.subplots(ncols=3, nrows=-1, naxes=10, axsize=(3, 2))
subplots would do the hard work of working out the correct values of
figsize from the passed arguments.
I put together a very simple gist here by way of example. (I was trying to plot all of scipy’s simple window functions.) If you use
None as the flag for the row or column that needs computing, everything else is simple to implement in the case that the user doesn’t do anything unexpected; the biggest changes would probably be to error handling and documentation.
Obviously this isn’t something that is difficult to implement outside the package, but it seems that it might be done frequently enough that I nice interface for users could be worthwhile.
P.S. And how about a
Figure.hide_unused_axes method so we don’t have to write:
from itertools import zip_longest fig, axes = plt.subplots() for data, ax in zip_longest(data_items, axes.flat): if data is None: ax.set_visible(False) else: # amazing plotting code