matplotlibをwxPythonで扱う

matplotlibで描いたグラフをwxPythonのパネル上に表示できると、matplotlibの機能を直接利用できるアプリケーションを作成することができます。次のコードは、3次元のグラフをパネル上にプロットさせて表示させた例です。

import matplotlib
matplotlib.interactive( True )
matplotlib.use( 'WXAgg' )

import wx
class myWxPlot(wx.Panel):
    def __init__( self, parent):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure
        
        self.parent = parent
        wx.Panel.__init__( self, parent)

        #matplotlib figure
        self.figure = Figure( None )
        self.figure.set_facecolor( (0.7,0.7,1.) )
        self.subplot = self.figure.add_subplot( 111 )
        #canvas
        self.canvas = FigureCanvasWxAgg( self, -1, self.figure )
        self.canvas.SetBackgroundColour( wx.Color( 100,255,255 ) )

        self._SetSize()
        self.draw()

    def _SetSize( self ):
        size = tuple( self.parent.GetClientSize() )
        self.SetSize( size )
        self.canvas.SetSize( size )
        self.figure.set_size_inches( float( size[0] )/self.figure.get_dpi(),
                                     float( size[1] )/self.figure.get_dpi() )

    def draw(self):
        from mpl_toolkits.mplot3d import Axes3D
        import numpy as np
        
        x = np.arange(-3, 3, 0.25)
        y = np.arange(-3, 3, 0.25)
        X, Y = np.meshgrid(x, y)
        Z = np.sin(X)+ np.cos(Y)
        
        ax = Axes3D(self.figure)
        ax.plot_wireframe(X,Y,Z)


app = wx.App()
frame = wx.Frame( None, size=(500,500) )
panel = myWxPlot( frame )
frame.Show()
app.MainLoop()

matplotlibがwxPythonを使って描画するように設定するため、下のように 'WXAgg' を指定します。

import matplotlib
matplotlib.interactive( True )
matplotlib.use( 'WXAgg' )

myWxPlotクラスにmatplotlib.figureとsubplot,canvas(matplotlibが表示するためのwxPython用キャンバス)をメンバ変数として持たせます。
キャンバスを扱うために、初期化子内で次のモジュールをインポートします。

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg

また、グラフを描画する図であるmatplotlib.figureを扱うのでこのモジュールも同時にインポートします。

from matplotlib.figure import Figure

2次元の図を描く場合は、figure上にsubplotを作成してそこに描画することになるので、subplotを一つメンバとして保持させておきます。
matplotlib.figureに背景色を付けるにはset_facecolorでfloatのタプルによって色を指定します。一方canvasの方はint型タプル(0〜255)で色を指定するので注意が必要です。

        #matplotlib figure
        self.figure = Figure( None )
        self.figure.set_facecolor( (0.7,0.7,1.) )
        self.subplot = self.figure.add_subplot( 111 )
        #canvas
        self.canvas = FigureCanvasWxAgg( self, -1, self.figure )
        self.canvas.SetBackgroundColour( wx.Color( 100,255,255 ) )

_SetSizeでfigureとcanvas、パネル自身のサイズを設定しており、drawメソッドで描画の処理を行っています。
2次元のグラフを描画するコードが次の例です。subplotにグラフをplotしています。

    def draw(self):
        import numpy as np

        theta = np.arange(0,200, 0.1)
        x = 2*np.cos(theta/7)
        y = 3*np.sin(theta/3)

        self.subplot.plot(x,y, '-r')

        self.subplot.set_title("Sample", fontsize = 12)
        self.subplot.set_xlabel("x")
        self.subplot.set_ylabel("y")
        self.subplot.set_xlim([-4, 4])
        self.subplot.set_ylim([-4, 4])

また下の例では、mpl_toolkits.mplot3dを利用してfigureに3次元のグラフをplotしています。

    def draw(self):
        from mpl_toolkits.mplot3d import Axes3D
        import numpy as np
        
        x = np.arange(-3, 3, 0.25)
        y = np.arange(-3, 3, 0.25)
        X, Y = np.meshgrid(x, y)
        Z = np.sin(X)+ np.cos(Y)
        
        ax = Axes3D(self.figure)
        ax.plot_wireframe(X,Y,Z)