为什么下面正文中的 python 绘图示例在看起来没有增加任何价值时使用子图?

Why does the python plotting example in the body below use subplot when it appears to add no value?

matplotlib 文档

https://matplotlib.org/gallery/lines_bars_and_markers/simple_plot.html

提供以下示例代码

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# Data for plotting
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)

fig, ax = plt.subplots()
ax.plot(t, s)

ax.set(xlabel='time (s)', ylabel='voltage (mV)',
       title='About as simple as it gets, folks')
ax.grid()

fig.savefig("test.png")
plt.show()

产生以下情节

可以使用以下代码生成完全相同的图

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
plt.plot(t,s)
plt.grid(True)
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.savefig("test.png")
plt.show()

不使用子图、斧头或图

我学会了如何使用第二种方法绘图。我最近才偶然发现第一种方法 虽然我可以想象它在做什么,但它似乎远不如第二种方法直观。

有人可以解释第一种方法背后的合理性吗,因为它似乎使非常简单的事情复杂化了?

pyplot 方法乍一看确实更直观。当然,这在很大程度上是主观的。因此,如果它适合您的需要,请随意使用它。

pyplot 是所谓的状态机。它将在 "current figure" 和 "current axes" 上运行。但是,它会像第一种情况一样调用当前对象的相应方法。例如。 plt.plot(...) 只会在内部调用 ax = plt.gca(); ax.plot(...)。因此,人们可能会决定直接使用有问题的对象,而不是依赖 pyplot 来查找这些对象。

此外,pyplot 不公开 matplotlib 的完整功能。例如。如果你想为你的滴答标签创建一个格式化程序,你将需要使用面向对象的接口,

plt.gca().xaxis.set_major_formatter(...)

在这种情况下,人们可能也会想直接使用轴 ax 来处理

ax.xaxis.set_major_formatter(...)

同样,如果你想写一个函数来绘制一些东西到一个轴上,你可以让这个函数将轴对象作为输入

def myplot(ax, data, **kwargs):
    ax.plot(data, label = "My plot", **kwargs)
    ax.set_title("My plot")
    ax.legend()

然后在任何轴上重复使用此类函数非常方便。也许你有一个带有坐标轴的图形,

fig, ax = plt.subplots()
myplot(ax, data)

或者你有几个不同图形的轴

fig1, (ax1, ax2) = plt.subplots(ncols=2)
fig2, (ax3, ax4) = plt.subplots(ncols=2)
myplot(ax2, data2)
myplot(ax4, data3)

还有一些情况,您根本不想使用 pyplot,例如将绘图嵌入到 GUI 中时,在这种情况下,您需要使用类似

的结构
fig = matplotlib.figure.Figure()
canvas = FigureCanvasQT(fig)
axes = fig.subplots(2,3)
axes[0,1].plot(...)

最后,应该指出的是,人们在 Whosebug 上询问的很多问题直接导致使用 pyplot 而不是面向对象的方法。这并不是说,你不应该使用它,但总的来说,如果你在使用 pyplot 时没有最大限度地注意 "current axes" 是什么,那么 pyplot 似乎会增加搬起石头砸自己脚的机会.

由于上述所有原因,matplotlib 得出的结论是,最好提倡使用面向对象的方法,即使对于问题中的非常简单的示例,它可能不那么直接采用。即使不使用面向对象的风格,理解它也是使用 matplotlib 的先决条件,即使对于中等复杂的绘图也是如此。