matplotlib函数约定:子图与单个图形

9 投票
1 回答
3654 浏览
提问于 2025-04-18 11:49

我对matplotlib中处理子图和单个图形时函数(是不是叫这个?)之间的细微差别感到很困惑。

举个例子:

如果我想在一个单独的图形上改变x轴的范围,我会用:plt.xlim()

而如果我想在子图上改变x轴的范围,我会用:ax.set_xlim()

这是为什么呢?有没有人能给我推荐一个网站,解释一下这些用法的规则?这个例子比较简单,因为我知道它们不同,并且知道怎么用,但还有很多我不知道的地方,我很难弄清楚——比如:

1) 如何在子图上应用一个集合:ax.collection(collection_name)。那在单个图形上怎么做呢?

2) 如何在子图上设置刻度标签:ax.xaxis.ticklabels(tick_labels)。那在单个图形上怎么做呢?

抱歉这是个新手问题!

1 个回答

12

你遇到的是pyplot/状态机接口和面向对象接口之间的区别。可以查看推荐使用matplotlib还是pylab进行绘图?如何将pyplot函数附加到图形实例上?来获取更详细的解释。

如果想要更长的教程,可以查看Matplotlib的结构

关于mpl中的对象层次结构也有一些混淆:

重要的类

Figure

整个图形。它会跟踪所有的子坐标轴、一些“特殊”的艺术元素(标题、图例等)以及画布。不用太担心画布,它很重要,因为它是实际绘制图形的对象,但作为用户,你几乎看不见它。

Axes

这就是你想象中的“图”,是包含数据区域的图像部分。它有2个或3个坐标轴对象(x、y,有时还有z),并且包含很多艺术元素

Axis

这些就像数字线一样的对象。它们负责设置图形的范围,并生成刻度和刻度标签。它们有一个Locator和一个Formatter,用来确定刻度的位置和生成标签。

Artist

基本上,图形上你能看到的所有东西都是艺术元素(包括FigureAxesAxis对象)。这包括Text对象、Line2D对象、collection对象、Patch对象……(你明白了)。当图形被渲染时,所有的艺术元素都会被(递归地)绘制到画布上。一个艺术元素只能在一个Axes中。

API层次

pylab

这基本上是一个命名空间,里面包含了很多东西(numpy、pyplot、mlab(与matplotlib一起提供)),通过from foo import *的方式批量导入。这在交互式工作中非常方便,但在脚本中不应该使用。最初的目标是这样的。

pyplot

这是一个状态机层,跟踪你所有打开的图形,并有“当前图形”(plt.gcf())和“当前坐标轴”(plt.gca())的概念。pyplot中的大多数函数都是非常简单的(程序生成的)包装器,实际上是调用面向对象层的(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

撰写回答