0

我正在尝试制作一个 wx.Notebook,每个页面上都有一个 FigureCanvas 和这些画布中的唯一图形/轴。问题是,如果图形大小(通过 fig.set_size_inches)是小数点后 2 位或更多位的浮点数,则不同页面上的图形将彼此略微重叠。我一生都无法理解为什么会发生这种情况以及如何解决它。

要查看重叠问题,您必须切换到选项卡 2,然后返回选项卡 1,重叠显示在第一个图表的底部。

我在说什么的图片

import wx

# Import Matplotlib
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

class MyFrame ( wx.Frame ):

    def __init__( self, parent ):

        # FORM BUILDER OUTPUT
        #########################
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 600,500 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

        bSizer9 = wx.BoxSizer( wx.VERTICAL )

        self.m_notebook2 = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_panel5 = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer10 = wx.BoxSizer( wx.VERTICAL )

        self.m_panel5.SetSizer( bSizer10 )
        self.m_panel5.Layout()
        bSizer10.Fit( self.m_panel5 )
        self.m_notebook2.AddPage( self.m_panel5, u"Page1", False )
        self.m_panel6 = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer11 = wx.BoxSizer( wx.VERTICAL )

        self.m_panel6.SetSizer( bSizer11 )
        self.m_panel6.Layout()
        bSizer11.Fit( self.m_panel6 )
        self.m_notebook2.AddPage( self.m_panel6, u"Page2", False )

        bSizer9.Add( self.m_notebook2, 1, wx.EXPAND |wx.ALL, 5 )

        self.SetSizer( bSizer9 )
        self.Layout()

        self.Centre( wx.BOTH )

        #########################

        graph1 = self.create_graph( self.m_panel5, size=(3, 2.255252) )
        graph2 = self.create_graph( self.m_panel6, size=(5.5556, 3.5) )

        ####################

    def create_canvas( self, panel, size ):
        fig = Figure()
        ax = fig.add_subplot(111)
        ax.set_xlim([0,10])
        ax.set_ylim([0,100])
        ax.axis('off')

        fig.set_size_inches( size )  # If this is a float to 3 decimals is causes problems

        canvas = FigureCanvas(panel, -1, fig)
        sizer = panel.GetSizer()
        sizer.Add(canvas)
        return(canvas)

    def create_graph( self, panel, size ):
        canvas = self.create_canvas(panel,size)
        ax = canvas.figure.axes[0]
        xdata = range(1,10)
        ydata = [x*x for x in xdata]
        ax.scatter( xdata, ydata )
        ax.bar( xdata, [100]*9, 0.5, 0, color='red' )
        ax.plot()
        return(ax)


class MyApp(wx.App):
    def OnInit(self):
        main = MyFrame(None)
        main.Show()
        return True

app = MyApp(0)
app.MainLoop()

print('Done')
4

2 回答 2

0

在 Windows 上尝试过代码(wxPython 2.9.5.1/mpl 1.3.1)并得到了相同的结果(第一个图底部的红色标记)。

我会以不同的方式解决这个问题,并指定绘图的大小,而不是在 matplotlib 中,而是在 wxPython 中。

更改代码时如下:

def __init__( self, parent ):
    ...
    graph2 = self.create_graph(#...
    self.Layout() # put this at the end

def create_canvas( self, panel, size ): # size can be omitted
    fig = Figure(dpi=96) # specify the dpi instead of the size
    ...
    # comment this out
    # fig.set_size_inches( size )

一切都正确绘制,尺寸更有意义。

编辑:问题出现了如何在没有具体指定英寸大小的情况下为 mpl 画布设置固定的纵横比。您可以在添加到 sizer 并写入时使用wx.SHAPED标志而不是wx.EXPAND

    bSizer9.Add( self.m_notebook2, 1, wx.SHAPED |wx.ALL, 5 )

这将保持纵横比在__init__.

于 2015-01-20T16:34:06.933 回答
0

一种解决方法是在页面之间切换时调用页面的 Layout() 方法。这是一个使用 wxPython 3 和 Python 2.7 在 Windows 7 上为我工作的示例:

import wx

# Import Matplotlib
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

class MyFrame ( wx.Frame ):

    def __init__( self, parent ):

        # FORM BUILDER OUTPUT
        #########################
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 600,500 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

        bSizer9 = wx.BoxSizer( wx.VERTICAL )

        self.m_notebook2 = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_notebook2.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onPageChanged)
        self.m_panel5 = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer10 = wx.BoxSizer( wx.VERTICAL )

        self.m_panel5.SetSizer( bSizer10 )
        self.m_panel5.Layout()
        bSizer10.Fit( self.m_panel5 )
        self.m_notebook2.AddPage( self.m_panel5, u"Page1", False )
        self.m_panel6 = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer11 = wx.BoxSizer( wx.VERTICAL )

        self.m_panel6.SetSizer( bSizer11 )
        self.m_panel6.Layout()
        bSizer11.Fit( self.m_panel6 )
        self.m_notebook2.AddPage( self.m_panel6, u"Page2", False )

        bSizer9.Add( self.m_notebook2, 1, wx.EXPAND |wx.ALL, 5 )

        self.SetSizer( bSizer9 )
        self.Layout()

        self.Centre( wx.BOTH )

        #########################

        graph1 = self.create_graph( self.m_panel5, size=(3, 2.255252) )
        graph2 = self.create_graph( self.m_panel6, size=(5.5556, 3.5) )

        ####################

    def create_canvas( self, panel, size ):
        fig = Figure()
        ax = fig.add_subplot(111)
        ax.set_xlim([0,10])
        ax.set_ylim([0,100])
        ax.axis('off')

        fig.set_size_inches( size )  # If this is a float to 3 decimals is causes problems

        canvas = FigureCanvas(panel, -1, fig)
        sizer = panel.GetSizer()
        sizer.Add(canvas)
        return(canvas)

    def create_graph( self, panel, size ):
        canvas = self.create_canvas(panel,size)
        ax = canvas.figure.axes[0]
        xdata = range(1,10)
        ydata = [x*x for x in xdata]
        ax.scatter( xdata, ydata )
        ax.bar( xdata, [100]*9, 0.5, 0, color='red' )
        ax.plot()
        return(ax)

    def onPageChanged(self, event):
        self.m_panel5.Layout()
        self.m_panel6.Layout()


class MyApp(wx.App):
    def OnInit(self):
        main = MyFrame(None)
        main.Show()
        return True

app = MyApp(0)
app.MainLoop()
于 2015-01-20T16:43:32.560 回答