在本文中,我们将探讨如何使用 matplotlib 模块让子图跨越多个网格行和列。
在 Python 可视化领域,matplotlib 库长期以来一直充当着中流砥柱的角色。尽管出现了像 seaborn、plotly、bokeh 等代码接口更简洁、功能更敏捷的竞争对手,但它依然保持着顽强的生命力。虽然 Matplotlib 在某些直观交互能力上可能不如这些后起之秀,但在探索性数据分析(EDA)的数据可视化任务中,它表现得非常出色,甚至超出了我们的预期。
在进行 EDA 时,我们经常会遇到这种情况:需要展示一组相关的图表,作为大图的一部分来直观地传达我们的见解。matplotlib 的 subplot 功能可以帮我们完成这项工作。然而,在某些特定情况下,我们可能希望合并几个子图,并且希望每个子图拥有不同的长宽比。
首先,我们需要导入 matplotlib 模块的 gridspec 子模块。
Python3
# import modules
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
# create objects
fig = plt.figure()
gs = GridSpec(4, 4, figure=fig)
我们首先需要创建一个 *GridSpec* 对象,它允许我们在整个图形中指定总行数和总列数,同时需要传入一个 figure 对象作为参数。
我们将 *GridSpec* 对象存储在一个名为 *gs* 的变量中,并指定我们需要在整个图形中设置 4 行 4 列。
**下面是一些让子图跨越多个网格行和列的程序示例:**
**示例 1:**
Python3
CODEBLOCK_2961b7a4
输出:
现在,我们需要确定每个子图将如何在总图中跨越行和列的细节。建议先在纸上画一个粗略的草图,规划好子图的布局,以防止它们重叠。确定好布局后,我们通过创建的 GridSpec 对象来传递这些信息。行/列长度的信息传递方式与我们平时对数组/数据框进行子集化操作时使用的列表索引符号相同,行和列的索引号从零开始,并使用 ‘:‘ 来指定范围。带有索引信息的 GridSpec 对象会被传递给 figure 对象的 add_subplot 函数。
我们为整个图形添加了一个总标题,并去除了刻度标记,以便更清晰地可视化布局,毕竟这里的主要目的是展示如何实现跨越多行/多列的子图。当您实际操作时,显然需要根据您的数据框添加坐标轴刻度、标签等,并调整间距和图形大小以适应这些绘图元素。
示例 2:
在这里,我们创建了一个显式函数来格式化图形的坐标轴,即隐藏子图的索引值。
Python3
# explictit function to hide index
# of sub plots in the figure
def formatAxes(fig):
for i, ax in enumerate(fig.axes):
ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
ax.tick_params(labelbottom=False, labelleft=False)
# import required modules
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
# create objects
fig = plt.figure(constrained_layout=True)
gs = GridSpec(3, 3, figure=fig)
# create sub plots as grid
ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1, :-1])
ax3 = fig.add_subplot(gs[1:, -1])
ax4 = fig.add_subplot(gs[-1, 0])
ax5 = fig.add_subplot(gs[-1, -2])
# depict illustration
fig.suptitle("GridSpec")
formatAxes(fig)
plt.show()
`
输出:
这在多变量时间序列绘图中可能会非常有用,我们可能希望在顶行展示跨越所有列的时间序列图,并在下方的其他子图中展示单变量或多变量的可视化结果。您可以通过指定总图中的行/列数以及各个子图的范围,来自定义您的“拼图”外观。
示例 3:
利用以下方法合并两个子图…