在 matplotlib 中优雅地组合两个图形

Posted

技术标签:

【中文标题】在 matplotlib 中优雅地组合两个图形【英文标题】:Combining two figures elegantly in matplotlib 【发布时间】:2021-11-30 17:45:21 【问题描述】:

您好,我在使用 matplotlib 显示然后整齐地保存 7 个子图时遇到问题。该图由第一行的饼图和第二行的直方图组成。

我已经设法让某些东西正常工作,但是在尝试将所有子图都放在一个图中时,我无法设法让某些东西达到良好的可读性。重要的是在保存文件时能够输出一个包含所有组件的png文件。

第一个示例是“正确的”,但在饼图和直方图之间产生了很大的空间:

这是一个代码“示例”(尽管不是我所拥有的,但这是与我可以分享的问题最接近的工作示例):

histo_1 = np.random.choice(500, 100, replace=True)
histo_2 = np.random.choice(250, 7000, replace=True)
histo_3 = np.random.choice(150, 1500, replace=True)
histo_4 = np.random.choice(2000, 250, replace=True)

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]

f = plt.figure(figsize = (14, 15))
sn.set()
sn.color_palette("hls", 8)

ax = f.add_subplot(2,4,1)
plt.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
plt.title("Distribution")

ax = f.add_subplot(2,4,2)
plt.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
plt.title("Distribution")

ax = f.add_subplot(2,4,3)
plt.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
plt.title("Distribution")

ax = f.add_subplot(2,4,5)
plt.hist(histo_1, bins='fd', color = "cornflowerblue", edgecolor='white', linewidth=1.2)
plt.title("Distribution 1")

ax1 = f.add_subplot(2,4,6)
plt.hist(histo_2, bins='fd', color = "indianred", edgecolor='white', linewidth=1.2)
plt.title("Distribution 2")

ax2 = f.add_subplot(2,4,7)
plt.hist(histo_3, bins='fd', color = "seagreen", edgecolor='white', linewidth=1.2)
plt.title("Distribution 3")

ax3 = f.add_subplot(2,4,8)
plt.hist(histo_3, bins='fd', color = "peru", edgecolor='white', linewidth=1.2)
plt.title("Distribution 4")

plt.tight_layout()
plt.show()

让它看起来不错的唯一方法是有两个分开的数字,例如:

histo_1 = np.random.choice(500, 100, replace=True)
histo_2 = np.random.choice(250, 7000, replace=True)
histo_3 = np.random.choice(150, 1500, replace=True)
histo_4 = np.random.choice(2000, 250, replace=True)

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]


f = plt.figure(figsize = (14, 15))
sn.set()
sn.color_palette("hls", 8)

ax = f.add_subplot(1,3,1)
plt.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
plt.title("Distribution")

ax = f.add_subplot(1,3,2)
plt.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
plt.title("Distribution")

ax = f.add_subplot(1,3,3)
plt.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
plt.title("Distribution")

plt.tight_layout()
plt.show()


f = plt.figure(figsize = (14, 8))

ax = f.add_subplot(1,4,1)
plt.hist(histo_1, bins='fd', color = "cornflowerblue", edgecolor='white', linewidth=1.2)
plt.title("Distribution 1")

ax1 = f.add_subplot(1,4,2)
plt.hist(histo_2, bins='fd', color = "indianred", edgecolor='white', linewidth=1.2)
plt.title("Distribution 2")

ax2 = f.add_subplot(1,4,3)
plt.hist(histo_3, bins='fd', color = "seagreen", edgecolor='white', linewidth=1.2)
plt.title("Distribution 3")

ax3 = f.add_subplot(1,4,4)
plt.hist(histo_3, bins='fd', color = "peru", edgecolor='white', linewidth=1.2)
plt.title("Distribution 4")

plt.tight_layout()
plt.show()

因此,我需要找到一种方法来减少图表/直方图之间的空间,或者找到一种方法将两个图形保存或拼接到一个文件中。

有人有建议吗?

谢谢

【问题讨论】:

【参考方案1】:

使用 Gridspec,我设置了一个两行四列的子图,调整了子图之间的高度,并将子图的整体高度和底部调整为它们的值。这会将保存的图像保持为一体,并且我在保存参数中省略了进一步的边距。

import matplotlib.pyplot as plt
import seaborn as sn
from matplotlib.gridspec import GridSpec

histo_1 = np.random.choice(500, 100, replace=True)
histo_2 = np.random.choice(250, 7000, replace=True)
histo_3 = np.random.choice(150, 1500, replace=True)
histo_4 = np.random.choice(2000, 250, replace=True)

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]

fig = plt.figure(figsize = (14, 14))# ,constrained_layout=True
sn.set()
sn.color_palette("hls", 8)

gs = GridSpec(nrows=2, ncols=4, hspace=0, figure=fig) #height_ratios=[1.0, 0.40], 
fig.subplots_adjust(top=0.65, bottom=0.25, hspace=0.0)

ax1 = fig.add_subplot(gs[0,0])
ax1.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
ax1.set_title("Distribution")

ax2 = fig.add_subplot(gs[0,1])
ax2.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
ax2.set_title("Distribution")

ax3 = fig.add_subplot(gs[0,2])
ax3.pie(sizes, labels = labels, autopct='%1.1f%%', textprops='fontsize': 13)
ax3.set_title("Distribution")

ax4 = fig.add_subplot(gs[1,0])
ax4.hist(histo_1, bins='fd', color = "cornflowerblue", edgecolor='white', linewidth=1.2)
ax4.set_title("Distribution 1")

ax5 = fig.add_subplot(gs[1,1])
ax5.hist(histo_2, bins='fd', color = "indianred", edgecolor='white', linewidth=1.2)
ax5.set_title("Distribution 2")

ax6 = fig.add_subplot(gs[1,2])
ax6.hist(histo_3, bins='fd', color = "seagreen", edgecolor='white', linewidth=1.2)
ax6.set_title("Distribution 3")

ax6 = fig.add_subplot(gs[1,3])
ax6.hist(histo_3, bins='fd', color = "peru", edgecolor='white', linewidth=1.2)
ax6.set_title("Distribution 4")

#plt.tight_layout()
plt.savefig('./data/combine_plot.png', bbox_inches='tight')
plt.show()

【讨论】:

非常感谢!我的代码需要一些工作,但我对结果非常满意,它让我可以完全控制网格!再次感谢,问候。

以上是关于在 matplotlib 中优雅地组合两个图形的主要内容,如果未能解决你的问题,请参考以下文章

在 matplotlib 中优雅地更改图框的颜色

如何使 matplotlib 图形看起来像这样专业地完成? [关闭]

Python机器学习(六十九)Matplotlib 其他类型图形

使用带有两个列表的matplotlib绘制图形

当我在 PyQt5 窗口中嵌入 Matplotlib 图形时,为啥有两个重复的轴标签?

Matplotlib:如何显示已关闭的图形