matplotlib:如何刷新figure.canvas
我不太明白怎么刷新FigureCanvasWxAgg这个实例。下面是一个例子:
import wx
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.NewId(), "Main")
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.figure = Figure(figsize=(1,2))
self.axe = self.figure.add_subplot(111)
self.figurecanvas = FigureCanvas(self, -1, self.figure)
self.buttonPlot = wx.Button(self, wx.NewId(), "Plot")
self.buttonClear = wx.Button(self, wx.NewId(), "Clear")
self.sizer.Add(self.figurecanvas, proportion=1, border=5, flag=wx.ALL | wx.EXPAND)
self.sizer.Add(self.buttonPlot, proportion=0, border=2, flag=wx.ALL)
self.sizer.Add(self.buttonClear, proportion=0, border=2, flag=wx.ALL)
self.SetSizer(self.sizer)
self.figurecanvas.Bind(wx.EVT_LEFT_DCLICK, self.on_dclick)
self.buttonPlot.Bind(wx.EVT_BUTTON, self.on_button_plot)
self.buttonClear.Bind(wx.EVT_BUTTON, self.on_button_clear)
self.subframe_opened = False
def on_dclick(self, evt):
self.subframe = SubFrame(self, self.figure)
self.subframe.Show(True)
self.subframe_opened = True
def on_button_plot(self, evt):
self.axe.plot(range(10), color='green')
self.figurecanvas.draw()
def on_button_clear(self, evt):
if self.subframe_opened:
self.subframe.Close()
self.figure.set_canvas(self.figurecanvas)
self.axe.clear()
self.figurecanvas.draw()
class SubFrame(wx.Frame):
def __init__(self, parent, figure):
wx.Frame.__init__(self, parent, wx.NewId(), "Sub")
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.figurecanvas = FigureCanvas(self, -1, figure)
self.sizer.Add(self.figurecanvas, proportion=1, border=5, flag=wx.ALL | wx.EXPAND)
self.SetSizer(self.sizer)
self.Bind(wx.EVT_CLOSE, self.on_close)
def on_close(self, evt):
self.GetParent().subframe_opened = False
evt.Skip()
class MyApp(wx.App):
def OnInit(self):
frame = MainFrame()
frame.Show(True)
self.SetTopWindow(frame)
return True
app = MyApp(0)
app.MainLoop()
我对以下操作顺序很感兴趣:
- 运行一个脚本
- 调整主窗口的大小
- 点击绘图按钮
- 双击图表
- 点击清除按钮
现在我在主窗口的图表上看到了一团乱麻。如果我调整窗口大小,图表会正确重绘。我的问题是,我应该在代码中添加什么,才能在不调整大小的情况下做到这一点?
这里的“乱麻”指的就是这样的情况:
http://img227.imageshack.us/img227/5407/mess.png
提前谢谢你。
1 个回答
17
正如我在评论中提到的,我认为图形画布的刷新并不是你的问题,实际上它正按照预期工作(根据它最后的状态重新绘制自己,也就是在你的子图中显示的样子)。我觉得你的问题更可能是wxFrame没有刷新。
解决这个问题最简单的方法是在你点击“清除”事件时让它自己调整大小。可以这样做:
def on_button_clear(self, evt):
if self.subframe_opened:
self.subframe.Close()
self.figure.set_canvas(self.figurecanvas)
self.axe.clear()
self.figurecanvas.draw()
self.SetSize((self.Size[0],self.figurecanvas.Size[1]))
设置大小会导致框架和它包含的所有控件被重新绘制。
不过,我觉得在两个图形画布之间共享你的图形是有风险的。我发现通过不同的点击和调整大小组合,可能会产生一些严重的错误。有时候,当子框架关闭时,你的图形会被垃圾回收,这样主框架就无法使用它了。