Axes(或 Subplots)简介#

Matplotlib Axes 是创建数据可视化的门户.一旦将 Axes 放置在 figure 上,就可以使用许多方法将数据添加到 Axes.Axes 通常有一对 Axis Artist,它们定义了数据坐标系,并包括添加注释(如 x 和 y 标签,标题和图例)的方法.

../../../_images/anatomy.png

Figure 的解剖#

在上图中,Axes 对象是使用 ax = fig.subplots() 创建的.图形上的所有其他内容都是使用此 ax 对象上的方法创建的,或者可以从中访问.如果我们想更改 x 轴上的标签,我们调用 ax.set_xlabel('New Label') ,如果我们要绘制一些数据,我们调用 ax.plot(x, y) .实际上,在上图中,唯一不属于 Axes 的 Artist 是 Figure 本身,因此 axes.Axes 类实际上是 Matplotlib 许多功能的门户.

请注意,Axes 对于 Matplotlib 的操作至关重要,以至于这里的很多材料都是 快速入门指南 中的重复内容.

创建 Axes#

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(ncols=2, nrows=2, figsize=(3.5, 2.5),
                        layout="constrained")
# for each Axes, add an artist, in this case a nice label in the middle...
for row in range(2):
    for col in range(2):
        axs[row, col].annotate(f'axs[{row}, {col}]', (0.5, 0.5),
                            transform=axs[row, col].transAxes,
                            ha='center', va='center', fontsize=18,
                            color='darkgrey')
fig.suptitle('plt.subplots()')

(Source code, png)

Axes 使用 Figure 对象上的方法或通过 pyplot 接口添加.这些方法在 创建图形在 Figure 中排列多个 Axes 中进行了更详细的讨论.但是,例如 add_axes 会手动将 Axes 放置在页面上.在上面的示例中, subplots 将一个子图网格放在 figure 上,并且 axs 是一个 (2, 2) 的 Axes 数组,每个 Axes 都可以添加数据.

还有许多其他方法可以将 Axes 添加到 Figure:

  • Figure.add_axes :手动放置 Axes. fig.add_axes([0, 0, 1, 1]) 使一个 Axes 填充整个图形.

  • pyplot.subplotsFigure.subplots :添加一个与上面的例子中一样的 Axes 网格.pyplot 版本返回 Figure 对象和 Axes 数组.请注意, fig, ax = plt.subplots() 会向 Figure 添加一个单独的 Axes.

  • pyplot.subplot_mosaicFigure.subplot_mosaic :添加一个带命名的 Axes 网格,并返回一个 axes 字典.对于 fig, axs = plt.subplot_mosaic([['left', 'right'], ['bottom', 'bottom']]) , axs['left'] 是顶行左侧的 Axes,而 axs['bottom'] 是跨越底部两列的 Axes.

有关如何在 Figure 上排列 Axes 网格的更多详细信息,请参见 在 Figure 中排列多个 Axes .

Axes 绘图方法#

大多数高级绘图方法都可以从 axes.Axes 类访问. 有关完整的精选列表,请参见 API 文档,有关示例,请参见 绘图类型 . 一个基本的例子是 axes.Axes.plot :

fig, ax = plt.subplots(figsize=(4, 3))
np.random.seed(19680801)
t = np.arange(100)
x = np.cumsum(np.random.randn(100))
lines = ax.plot(t, x)

(Source code, png)

请注意, plot 返回一个 lines Artists 列表,可以在之后对其进行操作,如 艺术家介绍 中所述.

下面是一个非常不完整的绘图方法列表. 同样,有关更多示例,请参见 绘图类型 ,有关完整方法列表,请参见 axes.Axes .

成对数据

plot , scatter , bar , step ,

数组对象

pcolormesh , contour , quiver , streamplot , imshow

统计分布

hist , errorbar , hist2d , pie , boxplot , violinplot

不规则网格数据

tricontour , tripcolor

Axes 标签和注释#

通常,我们希望使用 xlabel,ylabel 和 title 标记 Axes,并且通常我们希望有一个图例来区分绘图元素. Axes 类有许多方法来创建这些注释.

fig, ax = plt.subplots(figsize=(5, 3), layout='constrained')
np.random.seed(19680801)
t = np.arange(200)
x = np.cumsum(np.random.randn(200))
y = np.cumsum(np.random.randn(200))
linesx = ax.plot(t, x, label='Random walk x')
linesy = ax.plot(t, y, label='Random walk y')

ax.set_xlabel('Time [s]')
ax.set_ylabel('Distance [km]')
ax.set_title('Random walk example')
ax.legend()

(Source code, png)

这些方法相对简单,尽管可以在文本对象上设置许多 文本属性和布局 ,例如 fontsize,fontname,horizontalalignment.图例可能更复杂; 有关更多详细信息,请参见 图例指南 .

请注意,也可以使用 textannotate 将文本添加到 axes.这可能非常复杂:有关更多信息,请参见 文本属性和布局注释 .

Axes 限制,比例和刻度#

每个 Axes 都有两个(或更多) Axis 对象,可以通过 xaxisyaxis 属性访问这些对象.它们上面有大量的的方法,并且对于高度可定制的 Axis,阅读 Axis 上的 API 很有用. 但是,Axes 类为这些方法中最常见的方法提供了许多助手. 实际上,上面讨论的 set_xlabelset_label_text 的助手.

其他重要的方法设置 axes 的范围 ( set_xlim , set_ylim ),或者更根本地设置 axes 的比例. 因此,例如,我们可以使 Axis 具有对数刻度,并放大数据的子部分:

fig, ax = plt.subplots(figsize=(4, 2.5), layout='constrained')
np.random.seed(19680801)
t = np.arange(200)
x = 2**np.cumsum(np.random.randn(200))
linesx = ax.plot(t, x)
ax.set_yscale('log')
ax.set_xlim([20, 180])

(Source code, png)

Axes 类也提供了一些助手函数来处理 Axis 的刻度和标签.最直接的方法是 set_xticksset_yticks ,它们可以手动设置刻度位置,并可选择性地设置刻度标签.可以使用 minorticks_onminorticks_off 来切换次要刻度.

Axes 刻度和刻度标签的许多方面都可以使用 tick_params 进行调整.例如,要在轴的顶部而不是底部标记标签,将刻度线着色为红色,并将刻度标签着色为绿色:

fig, ax = plt.subplots(figsize=(4, 2.5))
ax.plot(np.arange(10))
ax.tick_params(top=True, labeltop=True, color='red', axis='x',
               labelcolor='green')

(Source code, png)

除了这些 Axes 级别的助手函数之外,对刻度,设置比例和控制 Axis 进行更细粒度的控制也是可以高度定制的.

Axes 布局#

有时,在数据空间中设置绘图的纵横比非常重要,我们可以使用 set_aspect 来实现:

fig, axs = plt.subplots(ncols=2, figsize=(7, 2.5), layout='constrained')
np.random.seed(19680801)
t = np.arange(200)
x = np.cumsum(np.random.randn(200))
axs[0].plot(t, x)
axs[0].set_title('aspect="auto"')

axs[1].plot(t, x)
axs[1].set_aspect(3)
axs[1].set_title('aspect=3')

(Source code, png)