Matplotlib和Seaborn(Figures、Axes 和 Subplot)

Figures、Axes 和 Subplot

到目前为止,你已经见过并使用 matplotlib 和 seaborn 练习过一些基本绘制函数。上个页面介绍了新的知识:通过 matplotlib 的 subplot() 函数创建两个并排显示的图表。如果你对该函数或 figure() 函数的原理有任何疑问,请继续阅读。此页面将使用 matplotlib 讨论可视化的基本结构,以及子图表在该结构下的工作原理。

matplotlib 中的可视化基本结构是 Figure 对象。每个 Figure 中将包含一个或多个 Axes 对象,每个 Axes 对象包含多个表示每个图表的其他元素。在最早的示例中,我们隐式地创建了这些对象。假设我们在 Jupyter notebook 中运行了以下表达式,从而创建一个直方图:

python 复制代码
plt.hist(data = df, x = 'num_var')

由于没有要在其中绘制图表的 Figure 区域,所以 Python 首先创建一个 Figure 对象。因为 Figure 没有以任何 Axes 开始来绘制直方图,所以在 Figure 里创建了一个 Axes 对象。最后,在该 Axes 中绘制直方图。 有必要了解这种对象层次结构,这样才能够更好地控制图表的布局和外观。对于上面的直方图,还有一种替代创建方式,即如下所示地显式设置 Figure 和 Axes:

python 复制代码
fig = plt.figure()
ax = fig.add_axes([.125, .125, .775, .755])
ax.hist(data = df, x = 'num_var')

figure() 会创建一个新的 Figure 对象,我们将对它的引用存储在了变量 fig 中。其中一个 Figure 方法是 .add_axes(),它会在 Figure 中创建新的 Axes 对象。该方法需要一个列表参数,用于指定 Axes 的维度:列表中的前两个元素表示 Axes 的左下角位置(即 Figure 的左下角象限),后两个元素分别指定了 Axes 宽度和高度。我们用变量 ax 引用 Axes。最后,我们像之前使用 plt.hist() 一样使用 Axes 方法 [.hist()] 要在 seaborn 中使用 Axes 对象,seaborn 函数通常使用"ax"参数指定要在哪个 Axes 上绘制图表。

python 复制代码
fig = plt.figure()
ax = fig.add_axes([.125, .125, .775, .755])
base_color = sb.color_palette()[0]
sb.countplot(data = df, x = 'cat_var', color = base_color, ax = ax)

在上述两种情形中,没必要明确地执行 Figure 和 Axes 创建步骤。在大多数情形下,可以直接原封不动地使用基本 matplotlib 和 seaborn 函数。每个函数都定位到一个 Figure 或 Axes,它们将自动定位到处理的最近一个 Figure 或 Axes。例如,我们详细了解下"直方图"页面是如何使用 subplot() 的:

python 复制代码
plt.figure(figsize = [10, 5]) # larger figure size for subplots

# example of somewhat too-large bin size
plt.subplot(1, 2, 1) # 1 row, 2 cols, subplot 1
bin_edges = np.arange(0, df['num_var'].max()+4, 4)
plt.hist(data = df, x = 'num_var', bins = bin_edges)

# example of somewhat too-small bin size
plt.subplot(1, 2, 2) # 1 row, 2 cols, subplot 2
bin_edges = np.arange(0, df['num_var'].max()+1/4, 1/4)
plt.hist(data = df, x = 'num_var', bins = bin_edges)

首先,plt.figure(figsize = [10, 5]) 会创建一个新的 Figure,并使用"figsize"参数将总体图表的宽和高分别设为 10 英寸和 5 英寸。虽然没有分配任何变量来返回函数输出,但是 Python 将隐式地知道后续需要 Figure 的图表调用将引用该 Figure。

然后,plt.subplot(1, 2, 1) 在 Figure 中创建一个新的 Axes,大小由 subplot() 函数参数确定。前两个参数要求将图表划分成一行两列,第三个参数要求在第一个槽位中创建一个新的 Axes。槽位从左到右并从上到下编号。注意,索引编号从 1 开始(而 Python 的索引编号通常从 0 开始)。(在此页面结束时,你将更清晰地了解索引知识)。Python 会隐式地将 Axes 设为当前 Axes,所以出现 plt.hist() 调用时,直方图画在左侧子图表中。

最后,plt.subplot(1, 2, 2) 会在第二个子图表槽位中创建一个新的 Axes,并将它设为当前 Axes。所以,第二次调用 plt.hist() 时,直方图画在右侧子图表中。

其他技巧

在结束之前,我们快速讲解下处理 Axes 和子图表的其他几种方式。上述技巧足以帮助你创建基本图表了,但是建议你记住以下技巧,以备不时之需。

如果在创建 Axes 对象后不分配它们,可以使用 ax = plt.gca() 检索当前 Axes,或者使用 axes = fig.get_axes() 获取 Figure fig 中的所有 Axes 列表。要创建子图表,可以像使用上述 plt.subplot() 一样使用 fig.add_subplot()。如果你已经知道你将创建大量子图表,可以使用 plt.subplots() 函数:

python 复制代码
fig, axes = plt.subplots(3, 4) # grid of 3x4 subplots
axes = axes.flatten() # reshape from 3x4 array into 12-element vector
for i in range(12):
    plt.sca(axes[i]) # set the current Axes
    plt.text(0.5, 0.5, i+1) # print conventional subplot index number to middle of Axes

需要特别注意的是,默认情况下,每个 Axes 的限制范围是 [0,1];如果我们通过 subplot() 创建子图表的话,我们会使迭代器计数器 i 加 1,从而获得子图表的索引。(参考资料:plt.sca()、plt.text())

相关推荐
程序边界34 分钟前
AI鉴伪技术:守护数字时代的真实性防线
人工智能
bryant_meng42 分钟前
【DeepID】《Deep Learning Face Representation from Predicting 10,000 Classes》
人工智能·深度学习·人脸识别·verification·identification
申耀的科技观察1 小时前
【观察】亚信科技:AI大模型交付引领,三大新引擎重构业务增长逻辑
大数据·人工智能·科技·重构
CONDIMENTTTT1 小时前
[机器学习]04-基于K近邻(KNN)的鸢尾花数据集分类
人工智能·机器学习
Cprsensors1 小时前
压力传感器选型铁三角:介质·安全·精度
人工智能·机器人·无人机
2501_924747112 小时前
驾驶场景玩手机识别准确率↑32%:陌讯动态特征融合算法实战解析
人工智能·算法·计算机视觉·智能手机
文火冰糖的硅基工坊4 小时前
[激光原理与应用-176]:测量仪器 - 频谱型 - AI分类与检测相对于传统算法的优缺点分析
人工智能·架构·光学
Jason_zhao_MR4 小时前
如何板端编译OpenCV并搭建应用--基于瑞芯微米尔RK3576开发板
人工智能·嵌入式硬件·mcu·opencv·物联网·计算机视觉·嵌入式
MobotStone4 小时前
AI时代的营销升级:从SEO到RAO的范式迁移
人工智能
程序员NEO4 小时前
GPT‑5 重磅发布
人工智能