I can't understand how to refresh FigureCanvasWxAgg instance. Here is the example:
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()
I'm interested in the following sequence of operations:
Now I get a mess on main frame plot. If I resize the frame it redraws properly. My question is what should I add to my code to do that without resizing?
By a "mess" I mean something like this:
http://img227.imageshack.us/img227/5407/mess.png
Thanks in advance.
To update the plot with x and y values, we use ion() function. To plot the line, we use plot() function. To define labels, we use xlabel() and ylabel() function. Then we update the variables x and y with set_xdate() and set_ydata() function.
As I said in the comments, I don't think that the figure canvas refresh is your problem, in fact I think it's doing exactly what it's supposed to (redrawing itself based on it's last state [ie as it was in your subplot]). I think your problem is more that the wxFrame is not refreshing.
The easiest way to fix that would be to make it resize itself on your "Clear" event. Something like:
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]))
The set size would cause the frame and all the controls it contains to be redrawn.
That said, I think sharing your figure between the two figurecanvas is dangerous. I was able to produce some serious errors by clicking/resizing things in different combinations. On occasion your figure would be garbage collected when the subframe was closed, making it unavailable to your main frame.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With