我正在学习使用matplotlib通过研究示例,许多示例似乎包括如下一行在创建一个单一的图之前…

fig, ax = plt.subplots()

下面是一些例子。

修改标记标签文本 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() is a function that returns a tuple containing a figure and axes object(s). Thus when using fig, ax = plt.subplots() you unpack this tuple into the variables fig and ax. Having fig is useful if you want to change figure-level attributes or save the figure as an image file later (e.g. with fig.savefig('yourfilename.png')). You certainly don't have to use the returned figure object but many people do use it later so it's common to see. Also, all axes objects (the objects that have plotting methods), have a parent figure object anyway, thus:

fig, ax = plt.subplots()

比这个更简洁:

fig = plt.figure()
ax = fig.add_subplot(111)

这只是一个补充。

下面的问题是,如果我想在图中有更多的子图呢?

正如在Doc中提到的,我们可以使用fig = plt。Subplots (nrows=2, ncols=2)在一个图形对象中设置一组带有网格(2,2)的子图。

然后我们知道,fig, ax = plt.subplots()返回一个元组,让我们试试fig, ax1, ax2, ax3, ax4 = plt。Subplots (nrows=2, ncols=2)首先。

ValueError: not enough values to unpack (expected 4, got 2)

它会引发一个错误,但不用担心,因为我们现在看到plot .subplots()实际上返回了一个包含两个元素的元组。第一个必须是一个图形对象,另一个应该是一组子图对象。

让我们再试一次:

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)

所以请记住,保持列表的结构与我们在图中设置的子图网格相同。

希望这对你有帮助。


作为问题和以上答案的补充,plot .subplots()和plot .subplot()之间还有一个重要的区别,请注意结尾缺少“s”。

可以使用plt.subplots()一次性创建所有的子图,它会以元组的形式返回子图的图形和轴(axis的复数)。人物可以理解为画布,你可以在上面画草图。

# create a subplot with 2 rows and 1 columns
fig, ax = plt.subplots(2,1)

然而,如果您想分别添加子图,则可以使用plt.subplot()。它只返回一个子图的轴。

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)

然而,使用plot .subplot(),必须为每个轴单独指定,这可能会变得很麻烦。


除了上面的答案,您还可以使用type(plt.subplots())检查对象的类型,它返回一个元组,另一方面,type(plt.subplot())返回matplotlib. axis ._subplots。AxesSubplot,你不能解包。


使用plt.subplots()很流行,因为它为您提供了一个Axes对象,并允许您使用Axes接口来定义图形。

另一种方法是使用全局状态接口plt。绘图等功能:

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对象的函数中,并且不依赖于全局状态 更容易过渡到有多个子情节的情况 一个一致/熟悉的界面,而不是在两个界面之间切换 访问matplotlib所有特性深度的唯一方法

创建全局状态版本是为了便于交互使用,并成为Matlab用户熟悉的接口,但在较大的程序和脚本中,这里概述的要点有利于使用Axes接口。

有一篇matplotlib博客文章更深入地探讨了这个主题:Pyplot vs面向对象接口

同时处理这两个问题相对容易。例如,我们可以总是询问当前轴:ax = plt.gca()(“获取当前轴”)。


fig.tight_layout ()

这样的功能是非常方便的,如果xticks_labels离开了plot-window,这样的行有助于适应xticks_labels和整个图表到窗口,如果自动定位图表在plt-window工作不正确。只有在plt窗口中使用fig-object时,此代码行才有效

fig, ax = plt.subplots(figsize=(10,8))

myData.plot(ax=ax)
plt.xticks(fontsize=10, rotation=45)

fig.tight_layout()
plt.show()