Search code examples
pythonlinuxwindowswxpython

FigureCanvasWxAgg not resizing properly in panel (or notebook) in linux


I've written a program in wxpython that works just fine in windows but when tested in lunix I have some Display issues that that all occur in linux.

Here is a testapp that demonstrates the problem with the resizing of the FigureCanvasWxAgg in a panel, as seen the panel it self follows the resizingevent but the FigureCanvasWxAgg doesn't follow, this however is not a problem in Windows.

import wx
import matplotlib.figure as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import wx.lib.inspection

class Test(wx.Frame):

    def __init__(self):
        super(Test, self).__init__(parent=None, id=-1)
        self.figure = plt.Figure()
        self.panel = wx.Panel(self, 1)
        self.figurepanel = FigureCanvas(self.panel, -1, self.figure)
        self.axes1 = self.figure.add_subplot(111)
        frame_box = wx.BoxSizer(wx.VERTICAL)
        frame_box.AddStretchSpacer(prop=1)
        frame_box.Add(self.panel, flag=wx.EXPAND, proportion=2)
        frame_box.AddStretchSpacer(prop=1)
        main_box = wx.BoxSizer(wx.HORIZONTAL)
        main_box.AddStretchSpacer(prop=1)
        main_box.Add(frame_box, flag=wx.EXPAND, proportion=1)
        main_box.AddStretchSpacer(prop=1)
        self.SetSizer(main_box)
        self.Show()
        self.Layout()

def main():
    app = wx.App()
    Test()
    wx.lib.inspection.InspectionTool().Show()
    app.MainLoop()

if __name__ == '__main__':
    main()

What I would be very grateful to have answered is:

  • How do I resolve this issue of reszing FigureCanvasWxAgg in linux
  • Is there any difference in the general way of GUI programming with wxPython on Windows and in Linux

Solution

  • I think I fixed the problem. The problem is caused by the wx.EVT_SIZE witch seems to be automatic in Windows but not in Linux. So to fix the problem in Linux all you have to do is to bind the the wx.Panel to the wx.EVT_SIZE and then define an apropriate eventhandler that takes care of the resizing. What did the trick for me was:

    #code beneath is a part if the __init__ metod
    self.panel = wx.Panel(self, -1)
    self.figurepanel = FigureCanvas(self.panel, -1, self.figure)
    self.panel.Bind(wx.EVT_SIZE, self.on_size)
    ....
    #the eventhandler for the panel. The method resizes the the figurepanel and the figure.
    def on_size(self, event):
        pix = self.panel.GetClientSize()
        self.figure.set_size_inches(pix[0]/self.figure.get_dpi(),
                                    pix[1]/self.figure.get_dpi())
        x,y = self.panel.GetSize()  
        self.figurepanel.SetSize((x-1, y-1))
        self.figurepanel.SetSize((x, y))
        self.figurepanel.draw()
        event.Skip()