防止matplotlib状态

2024-06-02 07:39:21 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我在matplotlib中创建了一个Axes对象并对其进行了变异(例如,通过绘制一些数据),然后我调用了一个函数,而没有将我的Axes对象传递给该函数,那么该函数仍然可以对我的Axes进行变异。例如:

import matplotlib.pyplot as plt
import numpy as np

def innocent_looking_function():
    #let's draw a red line on some unsuspecting Axes!
    plt.plot(100*np.random.rand(20), color='r')

fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20), color='b') #draw blue line on ax
#ax now has a blue line, as expected

innocent_looking_function()
#ax now unexpectedly has a blue line and a red line!

我的问题是:我能阻止这种全球变量行为吗?我知道我可以在调用任何innocent_looking_function()之前调用plt.close(),但是有没有什么方法可以使其成为默认值?在


Tags: 对象函数importmatplotlibasnplinefunction
1条回答
网友
1楼 · 发布于 2024-06-02 07:39:21

当然!您需要做的是在您生成图形时完全绕过pyplot状态机。在

它更冗长,因为您不能只调用fig = plt.figure()。在


首先,让我解释一下plt.gca()或{}是如何工作的。使用pyplot接口时,matplotlib存储所有已创建但未显示的地物管理器。图管理器基本上是图形的gui包装器。在

plt._pylab_helpers.Gcf是存储图形管理器并跟踪当前处于活动状态的图形管理器的单例对象。plt.gcf()返回_pylab_helpers.Gcf中的活动图形。每个Figure对象都跟踪自己的轴,因此plt.gca()只是plt.gcf().gca()。在

通常,当您调用plt.figure()时,它:

  1. 创建返回的figure对象
  2. 使用适当的后端为该图形创建一个FigureManager
  3. 图形管理器创建一个FigureCanvas、gui窗口(根据需要)和NavigationToolbar2(缩放按钮等)
  4. 然后,图管理器实例被添加到_pylab_helpers.Gcf的图列表中。在

这是我们想绕过的最后一步。在


下面是一个使用非交互式后端的快速示例。注意,因为我们不担心与绘图交互,所以我们可以跳过整个图形管理器,只创建一个Figure和{}实例。(从技术上讲,我们可以跳过FigureCanvas,但只要我们想将绘图保存到图像中,就需要它,等等)

import matplotlib.backends.backend_agg as backend
from matplotlib.figure import Figure

# The pylab figure manager will be bypassed in this instance. `plt.gca()`
# can't access the axes created here.
fig = Figure()
canvas = backend.FigureCanvas(fig)
ax = fig.add_subplot(111)

只是为了证明gca看不到这个轴:

^{pr2}$

有了交互性的支持,就更复杂了。您不能调用plt.show(),所以您需要自己启动gui的主循环。您可以“从头开始”(请参阅“嵌入matplotlib”示例中的任何一个),但是FigureManager抽象了备份的特定部分:

例如,使用TkAgg后端:

import matplotlib.backends.backend_tkagg as backend
from matplotlib.figure import Figure

fig = Figure()
ax = fig.add_subplot(111)

manager = backend.new_figure_manager_given_figure(1, fig)
manager.show()
backend.show.mainloop()

要使用其他后端之一,只需更改后端导入。例如,对于Qt4:

import matplotlib.backends.backend_qt4agg as backend
from matplotlib.figure import Figure

fig = Figure()
ax = fig.add_subplot(111)

manager = backend.new_figure_manager_given_figure(1, fig)
manager.show()
backend.show.mainloop()

这甚至可以与IPython笔记本中使用的nbagg后端配合使用。只需将后端导入更改为import matplotlib.backends.backend_nbagg as backend

相关问题 更多 >