如果我创建一个Axes对象matplotlib并进行变异(即通过绘制一些数据)然后我调用一个函数而不将我的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!
Run Code Online (Sandbox Code Playgroud)
我的问题是:我能否一般地阻止这种全局变量行为?我知道我可以在打电话plt.close()之前打电话给innocent_looking_function()但是有什么办法让这个默认吗?
Joe*_*ton 12
当然!您需要做的是pyplot在制作数字时完全绕过状态机.
它更加冗长,因为你不能只是打电话fig = plt.figure().
首先,让我解释一下如何plt.gca()或plt.gcf()有效.使用pyplot界面时,matplotlib会存储所有已创建但未显示的图形管理器.图管理器基本上是数字的gui包装器.
plt._pylab_helpers.Gcf是存储图形管理器的单例对象,并跟踪哪一个当前处于活动状态.plt.gcf()从中返回活动数字_pylab_helpers.Gcf.每个Figure对象都跟踪它自己的轴,所以plt.gca()就是这样plt.gcf().gca().
通常,当你打电话时plt.figure(),它:
FigureManager使用适当的后端为该数字创建一个FigureCanvasgui窗口(根据需要)和NavigationToolbar2(缩放按钮等)_pylab_helpers.Gcf图形列表中.这是我们想要绕过的最后一步.
这是使用非交互式后端的快速示例.请注意,因为我们不担心与绘图交互,所以我们可以跳过整个图管理器并只创建一个Figure和FigureCanvas实例.(从技术上讲,我们可以跳过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)
Run Code Online (Sandbox Code Playgroud)
只是为了证明gca看不到这个轴:
import matplotlib.pyplot as plt
import matplotlib.backends.backend_agg as backend
from matplotlib.figure import Figure
# Independent figure/axes
fig = Figure()
canvas = backend.FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot(range(10))
# gca() is completely unaware of this axes and will create a new one instead:
ax2 = plt.gca()
print 'Same axes?:', id(ax) == id(ax2)
# And `plt.show()` would show the blank axes of `ax2`
Run Code Online (Sandbox Code Playgroud)
通过交互式支持,触摸更加复杂.你不能打电话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()
Run Code Online (Sandbox Code Playgroud)
要使用其他后端之一,只需更改后端导入即可.例如,对于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()
Run Code Online (Sandbox Code Playgroud)
这实际上甚至nbagg适用于IPython笔记本中使用的后端.只需将后端导入更改为import matplotlib.backends.backend_nbagg as backend
| 归档时间: |
|
| 查看次数: |
512 次 |
| 最近记录: |