为什么许多示例在 Matplotlib/pyplot/python 中使用 `fig, ax = plt.subplots()`
Why do many examples use `fig, ax = plt.subplots()` in Matplotlib/pyplot/python
我正在通过研究示例来学习使用 matplotlib
,很多示例在创建单个图之前似乎都包含如下一行...
fig, ax = plt.subplots()
这里有一些例子...
- Modify tick label text
- http://matplotlib.org/examples/pylab_examples/boxplot_demo2.html
我看到这个函数用了很多,尽管这个例子只是试图创建一个图表。还有其他优势吗? subplots()
的官方演示在创建单个图表时也使用 f, ax = subplots
,之后它只引用 ax 。这是他们使用的代码。
# Just a figure and one subplot
f, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Simple plot')
plt.subplots()
是一个 returns 包含图形和轴对象的元组的函数。因此,当使用 fig, ax = plt.subplots()
时,您将这个元组解压到变量 fig
和 ax
中。如果您想更改图形级别的属性或稍后将图形保存为图像文件(例如使用 fig.savefig('yourfilename.png')
),则 fig
很有用。您当然不必使用返回的图形对象,但很多人稍后会使用它,因此很常见。此外,所有轴对象(具有绘图方法的对象)无论如何都有一个父图形对象,因此:
fig, ax = plt.subplots()
比这个更简洁:
fig = plt.figure()
ax = fig.add_subplot(111)
在这里补充一下。
下面的问题是如果我想在图中有更多的子图怎么办?
如文档中所述,我们可以使用 fig = plt.subplots(nrows=2, ncols=2)
在一个图形对象中设置一组具有 grid(2,2) 的子图。
那么我们知道,fig, ax = plt.subplots()
returns一个元组,我们先fig, ax1, ax2, ax3, ax4 = plt.subplots(nrows=2, ncols=2)
试试
ValueError: not enough values to unpack (expected 4, got 2)
它会引发错误,但不用担心,因为我们现在看到 plt.subplots()
实际上 returns 是一个包含两个元素的元组。第一个必须是图形对象,另一个应该是一组子图对象。
所以让我们再试一次:
fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(nrows=2, ncols=2)
并检查类型:
type(fig) #<class 'matplotlib.figure.Figure'>
type(ax1) #<class 'matplotlib.axes._subplots.AxesSubplot'>
当然,如果你使用参数为(nrows=1,ncols=4),那么格式应该是:
fig, [ax1, ax2, ax3, ax4] = plt.subplots(nrows=1, ncols=4)
所以只记得保持列表的构造与我们在图中设置的子图网格相同。
希望对您有所帮助。
作为问题和上述答案的补充,plt.subplots()
和 plt.subplot()
之间也有一个重要的区别,请注意最后缺少的 's'
。
可以使用 plt.subplots()
一次制作所有的子图,它 returns 子图的图形和轴(轴的复数)作为一个元组。人物可以理解为canvas画草图的地方
# create a subplot with 2 rows and 1 columns
fig, ax = plt.subplots(2,1)
然而,如果您想单独添加子图,则可以使用 plt.subplot()
。它 returns 只有一个子图的轴。
fig = plt.figure() # create the canvas for plotting
ax1 = plt.subplot(2,1,1)
# (2,1,1) indicates total number of rows, columns, and figure number respectively
ax2 = plt.subplot(2,1,2)
但是,plt.subplots()
是首选,因为它可以让您更轻松地直接自定义整个图形
# for example, sharing x-axis, y-axis for all subplots can be specified at once
fig, ax = plt.subplots(2,2, sharex=True, sharey=True)
而对于 plt.subplot()
,则必须为每个轴单独指定,这会变得很麻烦。
除了上述答案之外,您还可以使用 type(plt.subplots())
检查对象的类型,其中 returns 一个元组,另一方面,type(plt.subplot())
returns matplotlib.axes._subplots.AxesSubplot
无法解压。
使用 plt.subplots()
很受欢迎,因为它为您提供了一个 Axes 对象并允许您使用 Axes 接口来定义绘图。
替代方法是使用全局状态接口,plt.plot
等功能:
import matplotlib.pyplot as plt
# global state version - modifies "current" figure
plt.plot(...)
plt.xlabel(...)
# axes version - modifies explicit axes
ax.plot(...)
ax.set_xlabel(...)
所以 为什么 我们更喜欢 Axes?
- 它是可重构的 - 您可以将一些代码放入一个函数中,该函数采用 Axes 对象,并且不依赖于全局状态
- 更容易过渡到有多个子图的情况
- 一个 consistent/familiar 界面而不是在两个界面之间切换
- 深度访问matplotlib所有特征的唯一途径
全局状态版本以这种方式创建,以便于交互使用,并成为 Matlab 用户熟悉的界面,但在较大的程序和脚本中,此处概述的要点有利于使用 Axes 界面。
有一个 matplotlib 博客 post 更深入地探讨了这个主题:Pyplot vs Object Oriented Interface
处理两个世界相对容易。例如,我们可以始终询问当前坐标轴:ax = plt.gca()
(“获取当前坐标轴”)。
我正在通过研究示例来学习使用 matplotlib
,很多示例在创建单个图之前似乎都包含如下一行...
fig, ax = plt.subplots()
这里有一些例子...
- Modify tick label text
- http://matplotlib.org/examples/pylab_examples/boxplot_demo2.html
我看到这个函数用了很多,尽管这个例子只是试图创建一个图表。还有其他优势吗? subplots()
的官方演示在创建单个图表时也使用 f, ax = subplots
,之后它只引用 ax 。这是他们使用的代码。
# Just a figure and one subplot
f, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Simple plot')
plt.subplots()
是一个 returns 包含图形和轴对象的元组的函数。因此,当使用 fig, ax = plt.subplots()
时,您将这个元组解压到变量 fig
和 ax
中。如果您想更改图形级别的属性或稍后将图形保存为图像文件(例如使用 fig.savefig('yourfilename.png')
),则 fig
很有用。您当然不必使用返回的图形对象,但很多人稍后会使用它,因此很常见。此外,所有轴对象(具有绘图方法的对象)无论如何都有一个父图形对象,因此:
fig, ax = plt.subplots()
比这个更简洁:
fig = plt.figure()
ax = fig.add_subplot(111)
在这里补充一下。
下面的问题是如果我想在图中有更多的子图怎么办?
如文档中所述,我们可以使用 fig = plt.subplots(nrows=2, ncols=2)
在一个图形对象中设置一组具有 grid(2,2) 的子图。
那么我们知道,fig, ax = plt.subplots()
returns一个元组,我们先fig, ax1, ax2, ax3, ax4 = plt.subplots(nrows=2, ncols=2)
试试
ValueError: not enough values to unpack (expected 4, got 2)
它会引发错误,但不用担心,因为我们现在看到 plt.subplots()
实际上 returns 是一个包含两个元素的元组。第一个必须是图形对象,另一个应该是一组子图对象。
所以让我们再试一次:
fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(nrows=2, ncols=2)
并检查类型:
type(fig) #<class 'matplotlib.figure.Figure'>
type(ax1) #<class 'matplotlib.axes._subplots.AxesSubplot'>
当然,如果你使用参数为(nrows=1,ncols=4),那么格式应该是:
fig, [ax1, ax2, ax3, ax4] = plt.subplots(nrows=1, ncols=4)
所以只记得保持列表的构造与我们在图中设置的子图网格相同。
希望对您有所帮助。
作为问题和上述答案的补充,plt.subplots()
和 plt.subplot()
之间也有一个重要的区别,请注意最后缺少的 's'
。
可以使用 plt.subplots()
一次制作所有的子图,它 returns 子图的图形和轴(轴的复数)作为一个元组。人物可以理解为canvas画草图的地方
# create a subplot with 2 rows and 1 columns
fig, ax = plt.subplots(2,1)
然而,如果您想单独添加子图,则可以使用 plt.subplot()
。它 returns 只有一个子图的轴。
fig = plt.figure() # create the canvas for plotting
ax1 = plt.subplot(2,1,1)
# (2,1,1) indicates total number of rows, columns, and figure number respectively
ax2 = plt.subplot(2,1,2)
但是,plt.subplots()
是首选,因为它可以让您更轻松地直接自定义整个图形
# for example, sharing x-axis, y-axis for all subplots can be specified at once
fig, ax = plt.subplots(2,2, sharex=True, sharey=True)
plt.subplot()
,则必须为每个轴单独指定,这会变得很麻烦。
除了上述答案之外,您还可以使用 type(plt.subplots())
检查对象的类型,其中 returns 一个元组,另一方面,type(plt.subplot())
returns matplotlib.axes._subplots.AxesSubplot
无法解压。
使用 plt.subplots()
很受欢迎,因为它为您提供了一个 Axes 对象并允许您使用 Axes 接口来定义绘图。
替代方法是使用全局状态接口,plt.plot
等功能:
import matplotlib.pyplot as plt
# global state version - modifies "current" figure
plt.plot(...)
plt.xlabel(...)
# axes version - modifies explicit axes
ax.plot(...)
ax.set_xlabel(...)
所以 为什么 我们更喜欢 Axes?
- 它是可重构的 - 您可以将一些代码放入一个函数中,该函数采用 Axes 对象,并且不依赖于全局状态
- 更容易过渡到有多个子图的情况
- 一个 consistent/familiar 界面而不是在两个界面之间切换
- 深度访问matplotlib所有特征的唯一途径
全局状态版本以这种方式创建,以便于交互使用,并成为 Matlab 用户熟悉的界面,但在较大的程序和脚本中,此处概述的要点有利于使用 Axes 界面。
有一个 matplotlib 博客 post 更深入地探讨了这个主题:Pyplot vs Object Oriented Interface
处理两个世界相对容易。例如,我们可以始终询问当前坐标轴:ax = plt.gca()
(“获取当前坐标轴”)。