4、有状态与无状态方法

      好吧,在我们开始讨论闪亮的可视化之前,我们还需要更多的理论知识:有状态(基于状态,状态机)和无状态(面向对象,OO)接口之间的区别。

      上面,我们使用 import matplotlib.pyplot as plt 从 matplotlib 导入 pyplot 模块并将其命名为 plt。

      pyplot 中的几乎所有函数,例如 plt.plot(),都隐式地引用现有的当前图形和当前轴,或者如果不存在则重新创建它们。 隐藏在 matplotlib 文档中的是这个有用的片段:

“[With pyplot], simple functions are used to add plot elements (lines, images, text, etc.) to the current axes in the current figure.”

      前 MATLAB 用户可能会这样说:“plt.plot() 是一个隐式跟踪当前图形的状态机接口!” 这意味着:

      1)有状态接口使用 plt.plot() 和其他顶级 pyplot 函数进行调用。 在给定时间,您只操作一个图形或轴,您无需明确引用它。

      2)直接修改底层对象是面向对象的方法。 我们通常通过调用 Axes 对象的方法来完成此操作,该对象是表示绘图本身的对象。 从高层次来看,此过程的流程如下所示:

#yyds干货盘点#利用Matplotlib库画图(二)_java

      将这些结合在一起,pyplot 中的大多数函数也作为 matplotlib.axes.Axes 类的方法存在。 plt.plot() 可以归结为五行左右的代码:

def plot(*args, **kwargs):

... """An abridged version of plt.plot().""" ... ax = plt.gca() ... return ax.plot(*args, **kwargs)

def gca(**kwargs):

... """Get the current Axes of the current Figure.""" ... return plt.gcf().gca(**kwargs)

      调用 plt.plot() 只是获取当前 Figure 的当前 Axes 然后调用其 plot() 方法的便捷方法。这就是有状态接口总是“隐式跟踪”它想要引用的图的断言的意思。

      pyplot 是一批函数的所在地,这些函数实际上只是围绕 matplotlib 的面向对象接口的包装。 例如,对于 plt.title(),OO 方法中有相应的 setter 和 getter 方法,ax.set_title() 和 ax.get_title()。 (getter 和 setter 的使用在 Java 等语言中更受欢迎,但它是 matplotlib 的 OO 方法的一个关键特性。)

      调用 plt.title() 被翻译成这一行:gca().set_title(s, *args, **kwargs)。 这是它在做什么:

      1)gca() 抓取当前轴并返回它。

      2)set_title() 是设置该 Axes 对象的标题的 setter 方法。 这里的“方便”是我们不需要使用 plt.title() 显式指定任何 Axes 对象。

      同样,如果您花一些时间查看诸如 plt.grid()、plt.legend() 和 plt.ylabels() 等顶级函数的源代码,您会注意到它们都遵循相同的结构 使用 gca() 委托给当前 Axes,然后调用当前 Axes 的一些方法。 (这是底层的面向对象方法!)