Python Matplotlib说fig.canvas没有,所以我可以';不要使用无花果画布

Python Matplotlib说fig.canvas没有,所以我可以';不要使用无花果画布,python,canvas,matplotlib,plot,backend,Python,Canvas,Matplotlib,Plot,Backend,我没怎么用Matplotlib。根据某人的建议,我正在尝试尽可能使用面向对象的范例编写一些绘图代码,因此尝试使用纯Matplotlib(即不依赖pyplot)生成一些简单图形 我的代码的精简版本如下所示: 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 = rB

我没怎么用Matplotlib。根据某人的建议,我正在尝试尽可能使用面向对象的范例编写一些绘图代码,因此尝试使用纯Matplotlib(即不依赖pyplot)生成一些简单图形

我的代码的精简版本如下所示:

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

根据对的阅读,似乎
pyplot
负责一些幕后设置任务,最显著的是在地物对象和所需渲染器/后端之间建立连接。教程说:

在下面的示例中,我们使用matplotlib.pyplot.Figure()创建了一个地物实例,这是一种方便的 实例化地物实例并将其与用户连接 界面或绘图工具包FigureCanvas。正如我们将在下面讨论的那样, 这不是必需的–您可以直接使用PostScript、PDF Gtk+,或wxPython FigureCanvas实例,实例化您的图形 直接将它们连接起来——但既然我们在这里集中精力 在艺术家API上,我们将让pyplot为我们处理一些细节

不幸的是,这个特定的页面除了使用
pyplot.figure()
生成绘图外,并没有继续进行,所以我仍在尝试发现所需的步骤。再一次,我意识到pyplot可以简化这项任务——只是尝试探索所有的片段是如何组合在一起的

我看到了后端使用的基类的描述,我假设我需要分配
fig.canvas
一个
FigureCanvasBase
的子类

此外,我还验证了Python使用的是默认后端。所以我知道问题不是因为缺少后端造成的

>>> matplotlib.backends.backend
'Qt4Agg'
提前感谢您的帮助。总之,有两个问题:

  • 我错过了什么导致这一失败?是因为我没有为地物对象指定渲染器吗
  • 我提到我怀疑我需要
    FigureCanvasBase
    的子类才能继续前进。即使可以更优雅地解决这个问题,是否有方法在Python环境中搜索从FigureCanvabase继承的子类?这可能会在其他问题上派上用场
    您需要创建一个
    FigureCanvasAgg
    以手动打印,请尝试以下操作:

    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..FigureCanvas
    中找到
    FigureCanvasBase
    的子类。为什么不使用
    pyplot
    ?它为你处理了很多细节。如果要将matplotlib嵌入到更大的gui中,请查看是否真的想深入了解这一点,查看
    FigureManager
    类,但是它们仍然通过全局图形计数器机制耦合到
    pyplot
    。正如我在OP中指出的,有一个PR open(在1.5之前不会进入)来清理这个@tcaswell,这是一个学习练习。我只是想巩固我对后端/渲染器如何连接到更高级别对象的理解。我很难找到一个没有引用Pyplot就清楚地描述了结构的资源。这听起来有很好的理由,但在我阅读的参考资料中并不完全清楚。谢谢你的回复。