The solution is to place the matplotlib
Axes
objects returned by pd.DataFrame.hist()
into a figure with the desired layout. Unfortunately, placing new Axes
objects into an existing Figure
is a bit involved.
GridSpec
layout
Creating the layout you want is not too complicated using nested matplotlib.gridspec.GridSpec
s (see here for an example). Something like this.
import matplotlib.gridspec as gs
num_outer_columns = 2
num_outer_rows = 2
num_inner_columns = 2
num_inner_rows = 3
outer_layout = gs.GridSpec(num_outer_rows, num_outer_columns)
inner_layout = []
for row_num in range(num_outer_rows):
inner_layout.append([])
for col_num in range(num_outer_columns):
inner_layout[row_num].append(
gs.GridSpecFromSubplotSpec(
num_inner_rows,
num_inner_columns,
outer_layout[row_num, col_num]
)
)
You can create subplots within this grid using ax = plt.subplot(inner_layout[outer_row_num][outer_col_num][inner_row_num, inner_col_num])
and store the properly positioned ax
s for later.
Copying Axes
into an existing Figure
Your df.hist()
calls will produce something like this:
In [1]: dframe.hist(column=x, by=y)
Out[1]:
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x1189be160>,
<matplotlib.axes._subplots.AxesSubplot object at 0x118e3eb50>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x118e74d60>,
<matplotlib.axes._subplots.AxesSubplot object at 0x118ea8340>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x118e76d62>,
<matplotlib.axes._subplots.AxesSubplot object at 0x118ea9350>]],
dtype=object)
Now you just have to replace the ax
objects positioned earlier using your inner_layout
with the AxesSubplot
objects returned above. Unfortunately there isn't a convenient ax.from_axes(other_ax)
method to do this, so you'll have to copy the Axes
returned by df.hist()
over manually by following this answer.