簡體   English   中英

如何在wx.notebook中調整多個畫布的大小,浮點大小和重疊問題(WxPython,Matplotlib)

[英]How to size multiple canvases in wx.Notebook, issue with float sizes and overlap (WxPython, Matplotlib)

我正在嘗試制作一個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')

在Windows(wxPython 2.9.5.1/mpl 1.3.1)上嘗試過該代碼,並得到了相同的結果(第一幅圖底部的紅色標記)。

但是,我將以不同的方式解決該問題,並在watPython中而不是在matplotlib中指定圖的大小。

如下更改代碼時:

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__繪制的縱橫比。

一種解決方法是,每當您在頁面之間切換時,都將調用頁面的Layout()方法。 這是一個在Windows 7上使用wxPython 3和Python 2.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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM