详解matplotlib中pyplot和面向对象两种绘图模式之间的关系
本文深入解析matplotlib中pyplot命令式绘图与面向对象绘图的内在联系。通过源码分析揭示pyplot如何隐式调用Figure、Axes等对象,并重点介绍_gcf_helpers模块中Gcf单例类在追踪当前活动图像中的作用,阐明pyplot实为面向对象模式的便捷封装。
matplotlib提供了两种主要的绘图接口:一种是基于matplotlib.pyplot模块的命令式绘图,其风格类似于MATLAB指令;另一种则是面向对象式绘图,通过直接操作FigureCanvas(画布)、Figure(图像)和Axes(轴域)等对象来实现。
这两种模式并非完全割裂,而是通过特定机制紧密相连。pyplot绘图模式实际上在后台隐式地创建了面向对象模式所需的对象,其核心枢纽在于matplotlib._pylab_helpers模块中的单例类Gcf,该类负责追踪当前活动的画布及图像状态。
由此可见,matplotlib绘图的根本基础是面向对象式绘图,而pyplot绘图模式仅仅是一种简化操作的封装方式。
在深入分析源码之前,我们先通过实验来验证这一观点。
实验部分
首先通过一系列实验,观察我们日常常用的pyplot绘图模式的具体表现。
实验一:无绘图窗口显示的情况
from matplotlib import pyplot as plt
plt.show()
实验二:出现绘图结果的情况
from matplotlib import pyplot as plt
plt.plot([1,2])
plt.show()
实验三:出现绘图结果的情况
from matplotlib import pyplot as plt
plt.gca()
plt.show()
实验四:出现绘图结果的情况
from matplotlib import pyplot as plt
plt.figure()
# 或者plt.gcf()
plt.show()
pyplot模块绘图原理剖析
通过查阅pyplot模块中figure()、gcf()、gca()以及plot()等函数的源码,我们可以梳理出大致的工作逻辑。
- figure()函数:若已存在图像,则返回当前图像;若无现有图像,则初始化一个新图像并返回Figure对象。
- gcf()函数:若已存在图像,则返回当前图像;若无现有图像,则调用figure()函数,最终返回Figure对象。
- gca()函数:调用gcf()返回对象的gca方法,最终返回Axes对象。
- plot()函数:调用gca()返回对象的plot方法。
- pyplot模块中的其他绘图函数:均通过调用gca()函数的相关方法来实现。
综上所述,使用pyplot绘图模式时,无论是调用plot()还是其他绘图函数,若当前没有现成的图像对象,系统会先自动创建图像对象。同样,直接调用figure()、gcf()或gca()函数时,若没有现成图像对象,也会先创建图像对象。
进一步地,在matplotlib.pyplot模块的源码中发现了相关代码,因此需要查看matplotlib._pylab_helpers模块,其核心作用是追踪当前活动的画布及图像。
figManager = _pylab_helpers.Gcf.get_fig_manager(num)
figManager = _pylab_helpers.Gcf.get_active()
matplotlib._pylab_helpers模块专门用于管理pyplot绘图模式中的图像。该模块仅包含一个类——Gcf,其核心功能是追踪当前活动的画布及图像。
matplotlib.pyplot模块部分源码展示
def figure(num=None, # autoincrement if None, else integer from 1-N
figsize=None, # defaults to rc figure.figsize
dpi=None, # defaults to rc figure.dpi
facecolor=None, # defaults to rc figure.facecolor
edgecolor=None, # defaults to rc figure.edgecolor
frameon=True,
FigureClass=Figure,
clear=False,
**kwargs
):
figManager = _pylab_helpers.Gcf.get_fig_manager(num)
if figManager is None:
max_open_warning = rcParams['figure.max_open_warning']
if len(allnums) == max_open_warning >= 1:
cbook._warn_external(
"More than %d figures have been opened. Figures "
"created through the pyplot interface "
"(`matplotlib.pyplot.figure`) are retained until "
"explicitly closed and may consume too much memory. "
"(To control this warning, see the rcParam "
"`figure.max_open_warning`)." %
max_open_warning, RuntimeWarning)
if get_backend().lower() == 'ps':
dpi = 72
figManager = new_figure_manager(num, figsize=figsize,
dpi=dpi,
facecolor=facecolor,
edgecolor=edgecolor,
frameon=frameon,
FigureClass=FigureClass,
**kwargs)
return figManager.canvas.figure
def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
return gca().plot(
*args, scalex=scalex, scaley=scaley,
**({"data": data} if data is not None else {}), **kwargs)
def gcf():
"""
Get the current figure.
If no current figure exists, a new one is created using
`~.pyplot.figure()`.
"""
figManager = _pylab_helpers.Gcf.get_active()
if figManager is not None:
return figManager.canvas.figure
else:
return figure()
def gca(**kwargs):
return gcf().gca(**kwargs)
def get_current_fig_manager():
"""
Return the figure manager of the current figure.
The figure manager is a container for the actual backend-depended window
that displays the figure on screen.
If if no current figure exists, a new one is created an its figure
manager is returned.
Returns
-------
`.FigureManagerBase` or backend-dependent subclass thereof
"""
return gcf().canvas.manager
Gcf类源码展示
class Gcf:
"""
Singleton to maintain the relation between figures and their managers, and
keep track of and "active" figure and manager.
The canvas of a figure created through pyplot is associated with a figure
manager, which handles the interaction between the figure and the backend.
pyplot keeps track of figure managers using an identifier, the "figure
number" or "manager number" (which can actually be any hashable value);
this number is available as the :attr:`number` attribute of the manager.
This class is never instantiated; it consists of an `OrderedDict` mapping
figure/manager numbers to managers, and a set of class methods that
manipulate this `OrderedDict`.
Attributes
----------
figs : OrderedDict
`OrderedDict` mapping numbers to managers; the active manager is at the
end.
"""
至此,关于matplotlib中pyplot与面向对象两种绘图模式之间关系的详解已介绍完毕。如需了解更多相关内容,请搜索本站历史文章或继续浏览后续文章,感谢大家的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













