您遇到了 pyplot/状态机接口和 OO 接口之间的差异。有关详细说明,请参阅 Which is the recommended way to plot: matplotlib or pylab? 和 How can I attach a pyplot function to a figure instance?。
更多教程见Anatomy of Matplotlib
关于mpl中的对象层也有一些混淆:
重要课程
Figure
整个图。跟踪所有子 轴、少量“特殊”艺术家(标题、人物图例等)和 画布。不要太担心画布,它是至关重要的,因为它是实际绘制的对象以获得你的绘图,但作为用户,它或多或少对你来说是不可见的。
Axes
这就是您所认为的“绘图”,它是具有数据空间的图像区域。它有 2 或 3 个 轴 对象(x、y,有时还有 z),a 包含一大堆 艺术家。
Axis
这些是像数字线一样的物体。他们负责设置图形限制并生成刻度和刻度标签。他们有一个Locator 和一个Formatter 用于整理蜱的去向以及如何生成标签
Artist
基本上你在图中看到的所有东西都是艺术家(甚至是Figure、Axes 和Axis 对象)。这包括Text 对象、Line2D 对象、collection 对象、Patch 对象......(你明白了)。当图形被渲染时,所有的艺术家都被(递归地)绘制到 canvas。一个给定的艺术家只能在一个Axes中。
API 层
pylab
这基本上只是一个命名空间,一大堆东西(numpy、pyplot、mlab(附带 matplotlib))通过from foo import * 批量导入。这对于交互式工作来说非常方便,但您不应该将它用作脚本。这个的初衷
pyplot
这是一个状态机层,它跟踪所有打开的图形,并具有“当前图形”(plt.gcf()) 和“当前轴”(plt.gca()) 的概念。 pyplot 中的大多数函数都是对 OO 层调用(plt.foo() -> plt.gca().foo() 或 plt.gcf().foo() 取决于函数)的非常薄(程序生成)的包装器。同样,这可能方便,但很快就会变成限制/混淆/全局状态导致麻烦。
OO层
这是实际上管理艺术家创作的层(例如ax.plot(...) 创建了一堆Line2D 对象)。对于编写脚本或您打算重复使用的任何内容,这是您应该尝试使用的层。要编写自己的绘图函数,我建议编写如下函数:
def my_plotting_fun(ax, data, data, ...):
ax.do_stuff
return list_of_artists_added