如何在 matplotlib 中按列而不是行迭代子图

How to iterate subplots by columns instead of rows in matplotlib

假设我有一个 30 列的数据框,前 10 列是各种收集数据的 'mean',接下来的 10 列是 'median',最后 10 列是'mode'。例如,第 1 列是 height_mean,第 10 列是 height_median,第 20 列是 height_mode。第 2 列是 weight_mean,然后第 11 列是 weight_median,第 21 列是 weight_median

height_mean ... height_median ... height_mode ...
56 ... 58 ... 55 ...

我想创建一个 10x3 的子图,它为每个变量绘制均值、中值和众数图,并将它们相邻绘制,这样子图的每一行都是一个新变量。因此,子图的第一行将包含身高的均值、中值和众数图,子图的第二行将包含体重的均值、中值和众数,依此类推。

到目前为止,我有这个,它按照列在数据框中的顺序创建子图:

fig, axs = plt.subplots(10, 3, figsize=(20,20))

for count, ax in zip(df.columns, axs.ravel()):
    df_data.loc[:,[count]].boxplot(ax=ax)
plt.show()  

我试过这样做,但没有用:

for n, column in enumerate(df_columns):
    # add a new subplot iteratively
    ax = plt.subplot(10, 3, n + 1)
    df_data.iloc[:,[n]].boxplot(ax=ax)
    ax = plt.subplot(10, 3, n + 2)
    df_data.iloc[:,[n+9]].boxplot(ax=ax)
    ax=plt.subplot(10,3,n+3)
    df_data.iloc[:,[n+19]].boxplot(ax=ax)

要迭代子图 column-wise,最简单的方法是在拆解之前转置 axs,即 axs.T.ravel():

for col, ax in zip(df.columns, axs.T.ravel()):

这是一个最小的演示。请注意 weight_mean 现在如何低于 height_mean 而不是向右:

headers = ['height_mean', 'weight_mean', 'height_median', 'weight_median', 'height_mode', 'weight_mode']
df = pd.DataFrame(np.random.random((3, 6)), columns=headers)
#    height_mean  weight_mean  height_median  weight_median  height_mode  weight_mode
# 0     0.982351     0.548713       0.559040       0.497497     0.842977     0.738946
# 1     0.832716     0.660227       0.754149       0.286536     0.315156     0.312089
# 2     0.997460     0.290112       0.501917       0.974751     0.097419     0.559542

ncols = 3
nrows = len(df.columns) // ncols

fig, axs = plt.subplots(nrows, ncols, constrained_layout=True)
for col, ax in zip(df.columns, axs.T.ravel()):
    df[[col]].boxplot(ax=ax)