用新图更新wxpython图形画布

时间:2015-08-30 13:46:24

标签: python matplotlib wxpython

在wxPython应用程序中,我嵌入了一个带有matplotlib图形的FigureCanvas。我希望能够通过加载一个新图来切换图形。但是,该数字没有更新。

对类似主题的回答表明,panel.canvas.draw()panel.Refresh()应该可以解决问题,但我也尝试过panel.Update()panel.canvas.Refresh()。我担心只有当你想用相同的形图重绘画布时,这才有用吗?

所以我的问题是:如何替换画布中的图形并使其更新?

下面是一个小的(非工作)示例。首先,图形加载单轴。如果您从嵌入式shell中键入panel.LoadFigure(),则会创建一个包含2x2子图的新图并将其放入画布中。但新的数字没有显示出来。

import numpy as np
import wx
from wx.py.shell import Shell

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import matplotlib.pyplot as plt


class ShellPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.shell = Shell(self)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.shell, 1, wx.GROW)
        self.SetSizer(self.sizer)
        self.Layout()
        self.Fit()


class FigurePanel(wx.Panel):
    def __init__(self, parent):

        wx.Panel.__init__(self, parent)
        self.parent = parent
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.figure, ax = plt.subplots()
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.shellpanel = ShellPanel(self)
        s1 = wx.BoxSizer(wx.VERTICAL)
        s1.Add(self.canvas, 0, wx.GROW)
        s1.Add(self.shellpanel, 1 , wx.EXPAND)
        self.sizer.Add(s1, 5, wx.GROW)

        self.SetSizer(self.sizer)
        self.Layout()
        self.Fit()

    def LoadFigure(self):
        self.figure, ax = plt.subplots(2, 2)
        self.canvas.draw()
        self.Refresh()


class FigureFrame(wx.Frame):
    def __init__(self, parent, id, title, size):
        wx.Frame.__init__(self, parent, id, title, size=size)

if __name__ == "__main__":
    app = wx.App(False)
    fr = FigureFrame(None, -1, title='Figure Loader', size=(wx.DisplaySize()[0]/2, wx.DisplaySize()[1]*3/4))
    panel = FigurePanel(fr)
    fr.Show()
    app.MainLoop()

2 个答案:

答案 0 :(得分:1)

您是否有任何理由尝试在已定义的Figure上创建新的Axes而不是新的Figure

我会像这样编写你的代码:

def LoadFigure(self):
    self.figure.clf()  # clear current figure
    # add arbitrary number of new Axes
    self.figure.add_subplot(221)
    self.figure.add_subplot(222)
    self.figure.add_subplot(223)
    self.figure.add_subplot(224)
    self.canvas.draw()  # refresh canvas

编辑:关注您的评论后,我认为问题在于您创建了新的数据,但您的Canvas仍在引用旧的数字。我不知道你是否可以直接在FigureCanvas属性中更改它,也许有经验丰富的人可以提供更好的答案。目前,我会Destroy上一个画布,并用你的新人物创建一个新的FigureCanvas对象。

def LoadFigure(self):
    self.figure, ax = plt.subplots(2, 2)
    self.canvas.Destroy()
    self.canvas = FigureCanvas(self, -1, self.figure)
    self.canvas.draw()

答案 1 :(得分:0)

尝试使用图本身来制作你的数字,而不是pyplot。它通常对我有用,因为它为你提供了更多的即兴创作空间。

#!/usr/bin/python

# -*- coding: utf-8 -*-

import numpy as np
import wx
from wx.py.shell import Shell
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import matplotlib.pyplot as plt


class ShellPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.shell = Shell(self)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.shell, 1, wx.GROW)
        self.SetSizer(self.sizer)
        self.Layout()
        self.Fit()


class FigurePanel(wx.Panel):
    def __init__(self, parent):

        wx.Panel.__init__(self, parent)
        self.parent = parent
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.figure = Figure(figsize = (8,6.1), dpi =60)
        self.ax = self.figure.add_subplot(1,1,1)
        self.enlarged_figure = Figure(figsize = (8,6.1), dpi = 100)
        self.ax2 = self.enlarged_figure.add_subplot(2,1,2)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.canvas.Show()
        self.enlarged_canvas = FigureCanvas(self,-1,self.enlarged_figure)
        self.enlarged_canvas.Show()

        self.shellpanel = ShellPanel(self)
        s1 = wx.BoxSizer(wx.VERTICAL)
        s1.Add(self.canvas, 0, wx.GROW)
        s1.Add(self.shellpanel, 1 , wx.EXPAND)
        self.sizer.Add(s1, 5, wx.GROW)
        self.SetSizer(self.sizer)
        self.Layout()
        self.Fit()

    def LoadFigure(self):
        self.figure, ax = plt.subplots(2, 2)
        self.canvas.draw()
        self.Refresh()


class FigureFrame(wx.Frame):
    def __init__(self, parent, id, title, size):
        wx.Frame.__init__(self, parent, id, title, size=size)

if __name__ == "__main__":
    app = wx.App(False)
    fr = FigureFrame(None, -1, title='Figure Loader', size=(wx.DisplaySize()[0]/2, wx.DisplaySize()[1]*3/4))
    panel = FigurePanel(fr)
    fr.Show()
    app.MainLoop()

在'panel.LoadFigure()'中的shell类型中,新图形会很快显示然后消失。然后输入'panel.canvas.draw()',新的数字将在那里。然后键入'panel.LoadFigure()'来加载旧图。重复。

我不知道为什么在MainLoop()继续之后这个数字仍然隐藏但这可以快速解决你的问题。