目前此代码块生成 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) 将
,但它会留下第 8 个子图(作为一个空框)显示。上面的方法显式隐藏了我们不想要的图。zip
迭代器限制为前 7 列)
原始答案
你可以这样做:
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()
来间隔子图,使标签更易读并且子图更好地分开。
关于python - 使用 `statsmodels.api.qqplot()` 创建多个子图的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66722077/