嵌入在wxPython面板中的matplotlib图形不显示整个图形

时间:2018-04-06 19:03:01

标签: python matplotlib graph wxpython

我的目标是在同一个wxPython面板中生成多个相对较小的图形。另外,我想手动调整图形大小并将它们放在我想要的位置。这会导致问题,因为我的图表显示不正确。更改图形的大小不会更改图形本身,它只会切断图形的某些部分。如果你运行我的代码,我更容易理解我的意思。如您所见,右侧的图形已完全显示,但它太大了,我想让它变小一点。但是,左边较小的图表缺少图表的一半!有没有人知道如何解决这个问题?

    import wx
    import matplotlib as mpl
    mpl.use('WXAgg')

    from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
    from matplotlib.backends.backend_wx import NavigationToolbar2Wx
    from matplotlib.figure import Figure

    class MainFrame(wx.Frame):
        def __init__(self, parent):
            wx.Frame.__init__(self, None, size=(1200,900))

            self.panel_1 = Panel_one(self)

    class Panel_one(wx.Panel):
        def __init__(self, parent):
            wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)

            self.temp_graph = Graph(self, position=(50, 100), size=(400,400))
            self.temp_graph = Graph(self, position=(550, 100), size=(700, 700))

    class Graph(wx.Panel):
        def __init__(self, parent, position, size):
            wx.Panel.__init__(self, parent, pos=position, size=size)
            self.figure = Figure(None)
            self.canvas = Canvas(self, -1, self.figure)
            self.axes = self.figure.add_subplot(111)



    if __name__ == "__main__":
        app = wx.App(redirect=False)
        frame = MainFrame(None)
        frame.Show()
        app.MainLoop()

我找到了另一个有类似问题的线程,但线程的解决方案无法正常工作,图表仍然显示不正确。

1 个答案:

答案 0 :(得分:1)

我恭敬地不同意早先的回答。问题不在于Graph()中应包含sizer。使用sizer而不是固定位置绝对是一个好主意,但这不是问题的原因。

您看到的问题是matplotlib Figure的默认大小比较小的图形大。要解决此问题,您应指定图形大小和图形的dpi。一种方法是使用Graph.__init__()给出的大小来设置Figure的大小。例如:

import wx
import matplotlib
matplotlib.use('WXAgg')


from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure

class MainFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, None, size=(1200, 900))
        self.panel_1 = Panel_one(self)

class Panel_one(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)

        self.graph1 = Graph(self, position=(50, 100), size=(400, 400))
        self.graph2 = Graph(self, position=(500, 100), size=(700, 700))


class Graph(wx.Panel):
    def __init__(self, parent,  position, size, dpi=150):
        wx.Panel.__init__(self, parent, pos=position, size=size)

        # Note: here, set the figure size based on size of Graph 
        figsize = (size[0]*1.0/dpi, size[1]*1.0/dpi)
        self.figure = Figure(figsize, dpi=dpi)
        self.canvas = Canvas(self, -1, self.figure)
        self.axes = self.figure.add_subplot(111)


if __name__ == "__main__":
    app = wx.App(redirect=False)
    frame = MainFrame(None)
    frame.Show()
    app.MainLoop()

将适当地缩放Graph()

我肯定建议不使用绝对位置,而是使用sizer,例如

class Panel_one(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)

        self.graph1 = Graph(self, size=(400, 400))
        self.graph2 = Graph(self, size=(700, 700))

        # Note: here create a sizer and add your graphs to it
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.graph1, 0, wx.LEFT, 5)
        sizer.Add(self.graph2, 0, wx.LEFT, 5)
        self.SetSizer(sizer)


class Graph(wx.Panel):
    def __init__(self, parent,  size, dpi=150):
        wx.Panel.__init__(self, parent, size=size)
        fsize = (size[0]*1.0/dpi, size[1]*1.0/dpi)
        self.figure = Figure(fsize, dpi=dpi)
        self.canvas = Canvas(self, -1, self.figure)
        self.axes = self.figure.add_subplot(111)

最后,请允许我建议使用wxmplot(https://newville.github.io/wxmplot/),它有一个PlotPanel类,它将matplotlib图放在wxPython Panel上,例如:

from wxmplot import PlotPanel

class Panel_one(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)

        # Note: here use wxmplot.PlotPanel instead of your Graph class
        self.graph1 = PlotPanel(self, size=(400, 400))
        self.graph2 = PlotPanel(self, size=(700, 700))

        sizer = wx.BoxSizer(wx.HORIZONTAL) 
        sizer.Add(self.graph1, 0, wx.LEFT, 5)
        sizer.Add(self.graph2, 0, wx.LEFT, 5)
        self.SetSizer(sizer)