wxPython面板内matplotlib图形的大小不正确

wxPython面板内matplotlib图形的大小不正确,matplotlib,wxpython,Matplotlib,Wxpython,我试图在wxPython应用程序的面板中并排放置两个matplotlib图形。这曾经适用于wxPython 2.8,但不再适用于wxPython 3.0 在wxPython 2.8中,每个绘图的宽度是面板大小的一半。在wxPython 3.0中,绘图的宽度等于面板大小,这意味着仅显示左侧的绘图。展开窗口,最终显示右侧的绘图 下面是重现该问题的最简单示例 import wx from matplotlib.backends.backend_wxagg import FigureCanvasWxAg

我试图在wxPython应用程序的面板中并排放置两个matplotlib图形。这曾经适用于wxPython 2.8,但不再适用于wxPython 3.0

在wxPython 2.8中,每个绘图的宽度是面板大小的一半。在wxPython 3.0中,绘图的宽度等于面板大小,这意味着仅显示左侧的绘图。展开窗口,最终显示右侧的绘图

下面是重现该问题的最简单示例

import wx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(TestPlot(panel), 1, wx.EXPAND | wx.ALL, border=5)
        sizer.Add(TestPlot(panel), 1, wx.EXPAND | wx.ALL, border=5)
        panel.SetSizerAndFit(sizer)

class TestPlot(wx.Window):
    def __init__(self, *args, **kwargs):
        wx.Window.__init__(self, *args, **kwargs)

        self.canvas = FigureCanvasWxAgg(self, wx.ID_ANY, Figure())

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.canvas, 1, wx.ALL, border=20)
        self.SetSizerAndFit(sizer)

if __name__ == "__main__":
    app = wx.App()
    MainFrame(parent=None, size=(300, 300)).Show()
    app.MainLoop()
如何使此布局在wxPython 3.0中工作?

替换

    panel.SetSizerAndFit(sizer)


要最终将
wx.Frame
调整到
面板中的元素

,我在wxpython3.0上遇到了相同的问题

我认为问题在于
self.canvas
的默认最小大小太大

通过
self.canvas.SetMinSize(wx.size(1,1))

似乎解决了这个问题。虽然不是一种优雅的方式

以下是示例的固定版本

import wx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(TestPlot(panel), 1, wx.EXPAND | wx.ALL, border=5)
        sizer.Add(TestPlot(panel), 1, wx.EXPAND | wx.ALL, border=5)
        panel.SetSizer(sizer)
        # don't do Fit(), as it sets the canvases to its minimum size
        panel.Layout()

class TestPlot(wx.Window):
    def __init__(self, *args, **kwargs):
        wx.Window.__init__(self, *args, **kwargs)

        self.canvas = FigureCanvasWxAgg(self, wx.ID_ANY, Figure())
        # setting the minimum canvas size as small as possible
        self.canvas.SetMinSize(wx.Size(1,1))

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        # added wx.EXPAND so that the canvas can stretch vertically
        sizer.Add(self.canvas, 1, wx.ALL|wx.EXPAND, border=20)
        self.SetSizer(sizer)

if __name__ == "__main__":
    app = wx.App()
    MainFrame(parent=None, size=(300, 300)).Show()
    app.MainLoop()
希望这有帮助


在Windows 8.1/Python 2.7.9/matplotlib 1.4.3/wxpython 3.0.0.0上测试过,我一点也不知道wx框架,但从您的描述和代码气味来看,我猜问题在于wx改变了它处理
sizer.Add的方式(TestPlot(panel),1,wx.EXPAND | wx.all,border=5)
import wx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(TestPlot(panel), 1, wx.EXPAND | wx.ALL, border=5)
        sizer.Add(TestPlot(panel), 1, wx.EXPAND | wx.ALL, border=5)
        panel.SetSizer(sizer)
        # don't do Fit(), as it sets the canvases to its minimum size
        panel.Layout()

class TestPlot(wx.Window):
    def __init__(self, *args, **kwargs):
        wx.Window.__init__(self, *args, **kwargs)

        self.canvas = FigureCanvasWxAgg(self, wx.ID_ANY, Figure())
        # setting the minimum canvas size as small as possible
        self.canvas.SetMinSize(wx.Size(1,1))

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        # added wx.EXPAND so that the canvas can stretch vertically
        sizer.Add(self.canvas, 1, wx.ALL|wx.EXPAND, border=20)
        self.SetSizer(sizer)

if __name__ == "__main__":
    app = wx.App()
    MainFrame(parent=None, size=(300, 300)).Show()
    app.MainLoop()