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 Figure
and GridSpec
in turn):
-
naxes
to handle the number of required axes -
axsize
to determine the requiredfigsize
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))
And subplots
would do the hard work of working out the correct values of nrows
and 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 -1
or 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.
Cheers,
Matt
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