使用“statsmodels.api.qqplot()”创建多个子图的最有效方法是什么?

What is the most efficient way to create multiple subplots with `statsmodels.api.qqplot()`?

目前此代码块生成 8x1 子图。我希望代码块以最有效的方式生成 2x4 子图。请帮忙!

from sklearn.preprocessing import LabelEncoder
import statsmodels.api as sm
import pandas as pd

# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/wine.csv'
df = pd.read_csv(url, header=None)
normal_stat = df.loc[:,:7]

# generate subplots
for i in range(len(normal_stat.columns)):
    plt.figure(figsize=(20,10))
    ax=plt.subplot(2,4,1+i)
    sm.qqplot(df[normal_stat.columns[i]], line='s', ax=ax)
    ax.set_title(str(normal_stat.columns[i]) + ' QQ Plot')
    plt.show()

编辑:

仅绘制前 7 个 qq 图:

fig, axes = plt.subplots(ncols=4, nrows=2, sharex=True, figsize=(4*3, 2*3))
for k, ax in zip(df.columns, np.ravel(axes)):
    if k >= 7:
        ax.set_visible(False)
    else:
        sm.qqplot(df[k], line='s', ax=ax)
        ax.set_title(f'{k} QQ Plot')
plt.tight_layout()

注意:我们可以通过说 for k, ax in zip(df.columns[:7], np.ravel(axes))zip 迭代器限制在前 7 列,但它会留下显示的第 8 个子图(作为空框)。上面的方法明确隐藏了我们不想要的情节。

原回答

你可以这样做:

import numpy as np

fig, axes = plt.subplots(ncols=4, nrows=2, sharex=True, figsize=(4*3, 2*3))
for k, ax in zip(df.columns, np.ravel(axes)):
    sm.qqplot(df[k], line='s', ax=ax)
    ax.set_title(f'{k} QQ Plot')
plt.tight_layout()

说明

ncols=4, nrows=2 参数要求 8 个子图,排列成两行。但是生成的轴是长度为 4 的嵌套长度为 2 的列表。所以我们使用 np.ravel 来压平它。然后我们使用 zip()df 的列和这些轴上并发迭代。当达到最短的列和轴迭代器时,迭代器将停止,在本例中是 8 个轴(因此我们甚至不必显式切片 df 列)。

最后,plt.tight_layout() 用于 space 子图,使标签更易读,子图分离得更好。