matplotlib 为什么很多例子使用`fig,ax = plt.subplots()`

nwlqm0z1  于 2023-10-24  发布在  其他
关注(0)|答案(6)|浏览(108)

我正在通过学习示例来学习使用matplotlib,很多示例在创建单个情节之前似乎都包含了一行如下所示的内容。

fig, ax = plt.subplots()

这里有一些例子。。

我看到这个函数被使用了很多次,尽管这个例子只是试图创建一个单一的图表。还有其他的好处吗?subplots()的官方演示在创建一个单一的图表时也使用了f, ax = subplots,之后它只引用ax。这是他们使用的代码。

# Just a figure and one subplot
f, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Simple plot')
2vuwiymt

2vuwiymt1#

plt.subplots()是一个函数,它返回一个包含图形和轴对象的元组。因此,当使用fig, ax = plt.subplots()时,您可以将此元组解压缩为变量figax。如果您希望更改图形级别的属性或稍后将图形保存为图像文件,则使用fig非常有用(例如fig.savefig('yourfilename.png'))。你当然不需要使用返回的figure对象,但是很多人会在以后使用它,所以很常见。此外,所有axes对象(具有plotting方法的对象)都有一个父figure对象,因此:

fig, ax = plt.subplots()

比这个更简洁:

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

sqserrrh2#

这里只是一个补充。
下面的问题是,如果我想在图中有更多的子情节呢?
如文档中所述,我们可以使用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)

它会引发一个错误,但不用担心,因为我们现在看到plt.subplots()实际上返回了一个包含两个元素的元组。第一个必须是一个figure对象,另一个应该是一组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,nrows =4),那么格式应该是:

fig, [ax1, ax2, ax3, ax4] = plt.subplots(nrows=1, ncols=4)

因此,只需记住保持列表的结构与我们在图中设置的子图网格相同。
希望这对你有帮助。

3htmauhk

3htmauhk3#

作为对问题和上述答案的补充,plt.subplots()plt.subplot()之间也有一个重要的区别,请注意最后缺少的's'
你可以使用plt.subplots()来一次绘制所有的子图,它将子图的图形和轴(复数轴)作为元组返回。图形可以被理解为你画草图的画布。

# 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)


,而对于plt.subplot(),必须为每个轴单独指定,这可能变得很麻烦。

6rvt4ljy

6rvt4ljy4#

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

6gpjuf90

6gpjuf905#

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

全局状态版本是以这种方式创建的,易于交互使用,并且是Matlab用户熟悉的界面,但在较大的程序和脚本中,这里概述的要点有利于使用Axes接口。
有一篇matplotlib博客文章更深入地探讨了这个主题:Pyplot vs Object Oriented Interface
处理这两个世界相对容易。例如,我们可以总是要求当前轴:ax = plt.gca()(“获取当前轴”)。

ffscu2ro

ffscu2ro6#

fig.tight_layout()
这样的功能非常方便,如果xticks_labels超出plot-window,这样的一行有助于将xticks_labels和整个图表适应窗口,如果plt-window中图表的自动定位不正确。并且只有当您在plt-window中使用fig-object时,此代码行才有效

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

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

fig.tight_layout()
plt.show()

相关问题