



有时,将多个相关图形并排放置在同一图中但不在相同的轴域(axes)上,这是很有用的。子图允许我们在同一个图中生成由独立图形组成的图网格。在本节中,我们将看到如何使用子图在单个图中并排创建两个图形。
你需要准备绘制每个子图的数据。作为示例,我们将在第一个子图上绘制对函数 f ( x )= x 2 -1进行牛顿法(Newton's method)求解的前五次迭代结果,初始值为 x 0 =2;而在第二个子图上,我们将绘制迭代的误差。首先,我们定义一个生成器函数以获取迭代值:
这个例程会生成两个列表。第一个列表包含对函数应用牛顿法求解的数值,第二个列表包含近似值的误差:
以下步骤将演示如何创建包含多个子图的图形:
1.我们使用subplots例程创建一个新图形,并引用每个子图中的所有Axes对象,这些子图按一行两列的网格排列。我们还将tight_layout关键字参数设置为True,以自动调整生成图形的布局。这个参数设置并不是严格必要的,但在这种情况下它会产生比默认值更好的结果:
2.创建Figure和Axes对象之后,我们可以通过在每个Axes对象上调用相关的绘图方法来填充图形。对于第一个图(显示在左侧),我们在ax1对象上使用plot方法,该方法的签名与标准的plt.plot例程相同。然后,我们在ax1对象上调用set_title、set_xlabel和set_ylabel方法来分别设置标题以及x轴和y轴标签。我们还通过提供usetex关键字参数,对轴标签使用TeX格式化,如果你的系统上没有安装Te X,可以忽略这一点:
3.现在,我们可以使用ax2对象在第二个绘图形(显示在右侧)上绘制误差值。我们使用名为semilogy的另一种画图方法,它在y轴上使用对数刻度。这个方法的签名与标准的plot方法相同。同样,我们设置了轴标签和标题。如果你没有安装TeX,同样可以省略对usetex的使用:
这一系列命令的结果如图2.3所示。
图2.3 在同一个Figure对象上绘制多个子图
图2.3中,左图绘制了以牛顿法求解对函数的前五次迭代结果,右图则以对数刻度绘制了结果的近似误差。
在Matplotlib中,Figure对象只是一个包含特定大小绘图元素(如Axes)的容器。Figure对象通常只包含一个Axes对象,该对象占据整个图形区域,但它也可以在同一区域内包含任意数量的Axes对象。subplots例程执行了以下几个操作。首先,它创建一个新图形,然后在图形区域内创建了具有指定形状的网格。其次,在网格的每个位置添加新的Axes对象。再次,将新的Figure对象和一个或多个Axes对象返回给用户。如果只需要一个子图(一行一列,没有其他参数),那么将返回一个普通的Axes对象;如果需要一行或一列(分别有多列或多行)绘图区域,那么将返回一个Axes对象的列表;如果需要多行多列绘图区域,则返回一个列表的列表,其中的行是由Axes对象组成的列表。最后,我们可以在每个Axes对象上使用绘图方法,将图形填充到所需的图中。
在这个示例中,我们在左侧图形中使用了标准的plot方法,就像我们在之前的示例中看到的那样。然而,在右侧的图形中,我们使用了将坐标轴更改为对数刻度的绘图方式。这意味着轴上的每个单位代表的都是10的幂的变化,而不是一个单位的变化,因此0表示10 0 =1,1表示10,2表示100,以此类推。轴标签会自动更改以反映这种刻度变化。当数值有数量级的变化时,这种类型的缩放很有用,例如展示随着迭代次数的增加而得到的近似误差的情况。我们还可以使用semilogx方法在 x 轴上使用对数刻度,或使用loglog方法在两个轴上同时使用对数刻度。
在Matplotlib中,有多种创建子图的方法。如果你已经创建了Figure对象,那么可以使用Figure对象的add_subplot方法添加子图。另外,你还可以使用matplotlib.pyplot中的subplot例程将子图添加到当前图形中。如果尚不存在Figure对象,调用此方法时将先创建一个Figure对象。subplot例程是Figure对象上add_subplot方法的简便包装。
在前面的示例中,我们创建了两个在 y 轴上具有不同刻度的图,这演示了子图的许多可能用途之一。子图的另一个常见的用途是绘制矩阵中的数据,其中矩阵的列具有共同的 x 标签,行具有共同的 y 标签,这在多元统计中非常常见,用于研究各组数据之间的相关性。用于创建子图的plt.subplots例程接受sharex和sharey这两个关键字参数,允许坐标轴在所有子图或一行、一列中共享。此设置会影响坐标轴的比例和刻度。
Matplotlib通过为subplots例程提供gridspec_kw关键字参数来支持更高级的布局。更多信息请参阅matplotlib.gridspec的文档。