Matplotlib说fig.canvas为None,所以我不能使用fig.canvas.draw [英] Matplotlib says fig.canvas is None, so I can't use fig.canvas.draw

查看:535
本文介绍了Matplotlib说fig.canvas为None,所以我不能使用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:

  1. 我错过了什么导致失败?是因为我没有为图形对象分配渲染器吗?
  2. 我提到我怀疑我需要FigureCanvasBase的子类来继续前进.即使可以更好地解决问题,是否有办法在Python环境中搜索从FigureCanvasBase继承的子类?这在其他问题中可能会派上用场.
  1. What am I missing that is causing this to fail? Is it because I didn't assign the figure object a renderer?
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆