想象一下,我有一些葡萄酒数据集,我发现了前5个葡萄酒生产国:
# Find top 5 wine producing countries.
top_countries = wines_df.groupby('country').size().reset_index(name='n').sort_values('n', ascending=False)[:5]['country'].tolist()
现在我有了值,我尝试将结果绘制成10个图,5行2列。
fig = plt.figure(figsize=(16, 15))
fig.tight_layout()
i = 0
for c in top_countries:
c_df = wines_df[wines_df.country == c]
i +=1
ax1 = fig.add_subplot(5,2,i)
i +=1
ax2 = fig.add_subplot(5,2,i)
sns.kdeplot(c_df['points'], ax=ax1)
ax1.set_title("POINTS OF ALL WINES IN %s, n=%d" % (c.upper(), c_df.shape[0]), fontsize=16)
sns.boxplot(c_df['price'], ax=ax2)
ax2.set_title("PRICE OF ALL WINES IN %s, n=%d" % (c.upper(), c_df.shape[0]), fontsize=16)
plt.show()
即使有这个结果,我的子图仍然重叠。
我做错什么了吗?将python3.6
与matplotlib==2.2.2
一起使用
答案 0 :(得分:2)
正如托马斯·库恩(ThomasKühn)所说,在绘制之后,您必须移动tight_layout()
,例如:
fig = plt.figure(figsize=(16, 15))
i = 0
for c in top_countries:
c_df = wines_df[wines_df.country == c]
i +=1
ax1 = fig.add_subplot(5,2,i)
i +=1
ax2 = fig.add_subplot(5,2,i)
sns.kdeplot(c_df['points'], ax=ax1)
ax1.set_title("POINTS OF ALL WINES IN %s, n=%d" % (c.upper(), c_df.shape[0]), fontsize=16)
sns.boxplot(c_df['price'], ax=ax2)
ax2.set_title("PRICE OF ALL WINES IN %s, n=%d" % (c.upper(), c_df.shape[0]), fontsize=16)
fig.tight_layout()
plt.show()
如果仍然重叠(在某些情况下可能会发生这种情况),则可以使用以下方式指定填充:
fig.tight_layout(pad=0., w_pad=0.3, h_pad=1.0)
其中pad
是常规填充,w_pad
是水平填充,h_pad
是垂直填充。只要尝试一些值,直到您的绘图看起来不错。如果您想使图尽可能紧凑,那么(pad=0., w_pad=.3, h_pad=.3)
是一个好的开始。
另一种可能性是在图中指定constrained_layout=True
:
fig = plt.figure(figsize=(16, 15), constrained_layout=True)
现在您可以删除行fig.tight_layout()
。
编辑:
我偶然发现的另一件事:
您似乎在指定figsize
,以使其适合厘米(标准文本宽度:16cm)的标准DIN A4纸。但是matplotlib中的 figsize
以英寸为单位。因此,用figsize=(16/2.54, 15/2.54)
替换figsize可能会更好。
我知道,matplotlib内部使用英寸作为单位是绝对令人困惑的,因为考虑到这主要是科学界和使用matplotlib的数据工程师使用的(而这些通常使用SI单位)。正如ImportanceOfBeingErnest所指出的那样,关于如何实现除英寸以外的其他单位的讨论正在进行中。