Matplotlib说fig.canvas为None,所以我不能使用fig.canvas.draw [英] Matplotlib says fig.canvas is None, so I can't use fig.canvas.draw
问题描述
我没用过Matplotlib.根据某人的建议,我试图尽可能多地使用面向对象的范例编写一些绘图代码-因此尝试使用纯Matplotlib(即不依赖pyplot)生成一些简单的图形.
I haven't used Matplotlib much. Based on someone's advice, I'm trying to write some plotting codes using object-oriented paradigms as much as possible---and therefore trying to use pure Matplotlib (i.e. not relying on pyplot) to generate some simple figures.
我的代码的简化版本如下:
A stripped-down version of my code looks like this:
import matplotlib as mpl
time = [0,1,2,3,4]
cell = [1,2,1,2,1]
sample = [3,2,3,4,4]
(figHt, figWd) = (5, 8) # in
lBorderWidth = bBorderWidth = rBorderWidth = tBorderWidth = 0.1
lbwh = (lBorderWidth, bBorderWidth,
(1-lBorderWidth-rBorderWidth),
(1-tBorderWidth-bBorderWidth)) # left, bottom, width, height
fig = mpl.figure.Figure(figsize=(figHt, figWd))
ax = fig.add_axes(lbwh)
lines1, = ax.plot(time,cell,'k--')
lines2, = ax.plot(time,sample,'k-')
fig.legend([lines1,lines2],['p','q'],'upper left')
fig.canvas.draw()
但是当我运行它时,Python会在到达fig.canvas.draw()
时抱怨canvas
类型是None
.
But when I run it, Python complains when it reaches fig.canvas.draw()
that canvas
type is None
.
基于对 Matplotlib艺术家教程的阅读,看来pyplot
会照顾一些幕后的设置任务,其中最值得注意的是在Figure对象与所需的渲染器/后端之间建立连接.该教程说:
Based on a reading of the Matplotlib Artists tutorial, it seems like pyplot
takes care of a few behind-the-scenes setup tasks, most notably establishing the connection between the Figure object and the desired renderer/backend. The tutorial says:
在下面的示例中,我们使用matplotlib.pyplot.figure()创建一个Figure实例,这是用于 实例化Figure实例并将其与您的用户连接 界面或绘图工具箱FigureCanvas.正如我们将在下面讨论的那样, 这不是必需的–您可以直接使用PostScript,PDF Gtk +或wxPython FigureCanvas实例实例化您的图形 直接将它们自己连接起来-但是由于我们专注于这里 在Artist API上,我们将让pyplot为我们处理其中一些细节
In the example below, we create a Figure instance using matplotlib.pyplot.figure(), which is a convenience method for instantiating Figure instances and connecting them with your user interface or drawing toolkit FigureCanvas. As we will discuss below, this is not necessary – you can work directly with PostScript, PDF Gtk+, or wxPython FigureCanvas instances, instantiate your Figures directly and connect them yourselves – but since we are focusing here on the Artist API we’ll let pyplot handle some of those details for us
不幸的是,除了使用pyplot.figure()
生成绘图外,该特定页面没有进行其他操作,因此我仍在尝试发现所需的步骤.再次,我意识到pyplot可以简化此任务-只是试图了解所有部分如何组合在一起.
Unfortunately, that particular page doesn't proceed beyond generating plots with pyplot.figure()
, so I am still trying to discover what the required steps are. Again, I realize pyplot can simplify this task---just trying to grok how all the pieces fit together.
我看到了后端使用的基类的描述, FigureCanvasBase
,我假设我需要为FigureCanvasBase
的子类之一分配fig.canvas
.
I saw this description of a base class used by backends, FigureCanvasBase
, and I assume that I need to assign fig.canvas
one of FigureCanvasBase
's subclasses.
我还验证了Python使用的是默认后端.因此,我知道问题不是由缺乏后端引起的.
Also, I verified that Python is using a default backend. So I know the problem isn't caused by lack of a backend.
>>> matplotlib.backends.backend
'Qt4Agg'
在此先感谢您的帮助.总之,有两个问题:
Thanks in advance for any help. In summary, two questions:
- 我错过了什么导致失败?是因为我没有为图形对象分配渲染器吗?
- 我提到我怀疑我需要
FigureCanvasBase
的子类来继续前进.即使可以更好地解决问题,是否有办法在Python环境中搜索从FigureCanvasBase继承的子类?这在其他问题中可能会派上用场.
- What am I missing that is causing this to fail? Is it because I didn't assign the figure object a renderer?
- I mentioned that I suspected I needed a subclass of
FigureCanvasBase
to move forward. Even if the problem can probably be solved more elegantly, is there a way to search the Python environment for subclasses that inherit from FigureCanvasBase? This might come in handy in other problems.
推荐答案
您需要创建一个FigureCanvasAgg
以便手动进行绘制,请尝试以下操作:
You need to create a FigureCanvasAgg
in order to plot manually, try this:
import matplotlib as mpl
mpl.use('Agg') #setup the backend
import matplotlib.figure as mfigure
from matplotlib.backends.backend_agg import FigureCanvasAgg #canvas
time = [0,1,2,3,4]
cell = [1,2,1,2,1]
sample = [3,2,3,4,4]
(figHt, figWd) = (5, 8) # in
lBorderWidth = bBorderWidth = rBorderWidth = tBorderWidth = 0.1
lbwh = (lBorderWidth, bBorderWidth,
(1-lBorderWidth-rBorderWidth),
(1-tBorderWidth-bBorderWidth)) # left, bottom, width, height
fig = mfigure.Figure(figsize=(figHt, figWd))
canvas = FigureCanvasAgg(fig) #create the canvas
ax = fig.add_axes(lbwh)
lines1, = ax.plot(time,cell,'k--')
lines2, = ax.plot(time,sample,'k-')
fig.legend([lines1,lines2],['p','q'],'upper left')
fig.savefig('test.png') #save the figure
注意:您可以在matplotlib.backends.<your backend>.FigureCanvas<your backend>
这篇关于Matplotlib说fig.canvas为None,所以我不能使用fig.canvas.draw的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!