2次元グラフを作成するアプリ

2次元グラフを作成するアプリをwxPythonで作成した。インターフェースとしては
はてなグラフと似たような感じになっている(機能は全然足りないが)。

使い方は次の通り。
下のソースコード(plot2d.py)からこのアプリは起動できる。起動方法は、

% python plot2d.py

起動の後、一番上の表へ、x、yの値を入力する。一組入力したら"Add"ボタンを押す。
そうすると、その下の表に入力した値が移される。さらに一組入力して"Add"ボタンを押して
値を追加していく。全部の値を入力し終えたら"Plot"ボタンを押す。
すると2次元グラフが作成され、別ウィンドウで開く。
予想以上にきれいなグラフが描けそうだ。matplotlibはすばらしい。ただし、グラフをプロットするときに表示されたウィンドウから画像ファイルに保存しようとしてもjpgとかbmpとかがこのままでは選べない。もう少し悩むか。

plot2d.pyは次の通り。

import wx
import wx.grid as gridlib
from pylab import *

class SelectPoints(gridlib.Grid):
    """ making table 1 for data input """
    def __init__(self, parent):
        gridlib.Grid.__init__(self, parent, -1)

        pointx = gridlib.GridCellFloatEditor(1,5)
        pointy = gridlib.GridCellFloatEditor(1,5)
        self.CreateGrid(1,2)

        self.SetColLabelValue(0, "x")
        self.SetColLabelValue(1, "y")
        self.SetRowLabelValue(0, "Value")

        self.SetCellEditor(0,0,pointx)
        self.SetCellEditor(0,1,pointy)
        self.SetCellValue(0,0,"0.00000")
        self.SetCellValue(0,1,"0.00000")

class SummaryPoints:
    """ making table 2 for summarizing sampling points """
    def __init__(self, parent):
        self.LISTctl = wx.ListCtrl(parent, -1, size=(250,100),
                                   style=wx.LC_REPORT|wx.LC_HRULES)
        self.LISTctl.InsertColumn(0, "Num")
        self.LISTctl.InsertColumn(1, "x")
        self.LISTctl.InsertColumn(2, "y")
        
class MyApp(wx.App):
    def OnInit(self):
        frame = wx.Frame(None, -1, 'Plot 2D', size=(360, 270))
        
        Pan1 = wx.Panel(frame, -1)
        self.SmplPN = 0
        self.SmplPx = []
        self.SmplPy = []
        
        self.SelectPoints = SelectPoints(Pan1)
        self.SummaryPoints = SummaryPoints(Pan1)
        Btn0 = wx.Button(Pan1, wx.ID_ADD)
        Btn1 = wx.Button(Pan1, -1, "Plot")
        Btn0.Bind(wx.EVT_BUTTON, self.AddPoint)
        Btn1.Bind(wx.EVT_BUTTON, self.MakePlot)
        
        sizer1 = wx.BoxSizer(wx.HORIZONTAL)
        sizer2 = wx.BoxSizer(wx.VERTICAL)
        sizer3 = wx.BoxSizer(wx.VERTICAL)

        sizer2.Add(Btn0, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer2.Add(Btn1, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer1.Add(self.SelectPoints, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer1.Add(sizer2, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer3.Add(sizer1, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer3.Add(self.SummaryPoints.LISTctl, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        
        Pan1.SetSizer(sizer3)
        frame.Show()
        
        return True

    def AddPoint(self, event):
        """ copy values in table 1 into table 2 """
        self.SmplPN += 1
        self.SmplPx.append(self.SelectPoints.GetCellValue(0,0))
        self.SmplPy.append(self.SelectPoints.GetCellValue(0,1))

        self.SummaryPoints.LISTctl.InsertStringItem(self.SmplPN-1,
                                                    str(self.SmplPN))
        self.SummaryPoints.LISTctl.SetStringItem(self.SmplPN-1, 1,
                                                 self.SmplPx[self.SmplPN-1])
        self.SummaryPoints.LISTctl.SetStringItem(self.SmplPN-1, 2,
                                                 self.SmplPy[self.SmplPN-1])
        
    def MakePlot(self, event):
        """ making 2-D plot with points in table 2 """
        lines = plot(self.SmplPx, self.SmplPy, 'k')
        setp(lines, color='r', linewidth=2.0)
        xlabel('x')
        ylabel('y')
        title('A plot')
        show()

app = MyApp()
app.MainLoop()

(1月24日:追記)
このままだと不安定であることが判明。一度グラフを表示して、そのグラフのウィンドウを閉じ、再びグラフを表示すると必ず強制的に終了してしまう。原因がよくわからない。今のままだと、グラフを描けるのは一度きり。