数式のグラフ化プログラム(2)

昨日の続き。完成した。evalを教えていただいた方、ありがとうございます。

  • 使い方
    • Pythonでの記法に従い、xの関数形を入力する
    • グラフ化するxの範囲を指定する。最小と最大値
    • ボタンを押すと縦軸y、横軸xでグラフを表示する
  • 起動画面

  • 実行例


グラフの絵をpngファイルに落して貼り付けるのだが、表示すると汚いな。

ソースは以下の通り。

# coding: utf-8
# -------------------------------------------------------------------
# PlotTool                               ver.1.0 (2008/12/04)
#                                               
# -------------------------------------------------------------------
import wx
import os
from pylab import *

class MainFrame(wx.Frame):
    def __init__(self, id, title):
        width, height = 600, 700
        wx.Frame.__init__(self, id, title=u"Plot Tool",
                          size=wx.Size(width, height))
        
        self.current = "  "
        self.sb = self.CreateStatusBar(2)
        self.sb.SetStatusWidths([-1, 150])
        self.sb.SetStatusText(self.current)

        Sizer0 = wx.BoxSizer(wx.VERTICAL)
        Sizer1 = wx.BoxSizer(wx.HORIZONTAL)
        Sizer2 = wx.BoxSizer(wx.HORIZONTAL)
        
        Pan = wx.Panel(self, -1)
        StTxt1 = wx.StaticText(Pan, -1, u"数式:")
        self.TxtCtl1 = wx.TextCtrl(Pan, -1, "", size=(300,-1))
        self.TxtCtl2 = wx.TextCtrl(Pan, -1, "", size=(100,-1))
        self.TxtCtl3 = wx.TextCtrl(Pan, -1, "", size=(100,-1))
        StTxt2 = wx.StaticText(Pan, -1, u"【数式の入力はPythonでの記法に従ってください】")
        BtnPlt = wx.Button(Pan, -1, u"数式をプロットする")
        StTxt3 = wx.StaticText(Pan, -1, u"xの表示範囲:")
        StTxt4 = wx.StaticText(Pan, -1, u"から")
        StTxt5 = wx.StaticText(Pan, -1, u"まで")

        bmp = wx.EmptyBitmap(500,500)
        self.bmpFlag = wx.StaticBitmap(Pan, -1, bmp)
        self.bmpFlag.SetBitmap(bmp)   
        
        BtnPlt.Bind(wx.EVT_BUTTON, self.OnPlot)

        Sizer1.Add(StTxt1, 0, wx.ALL, 2)
        Sizer1.Add(self.TxtCtl1, 0, wx.ALL, 2)
        Sizer1.Add(BtnPlt, 0, wx.RIGHT, 2)
        Sizer2.Add(StTxt3, 0, wx.ALL, 2)
        Sizer2.Add(self.TxtCtl2, 0, wx.ALL, 2)
        Sizer2.Add(StTxt4, 0, wx.ALL, 2)
        Sizer2.Add(self.TxtCtl3, 0, wx.ALL, 2)
        Sizer2.Add(StTxt5, 0, wx.ALL, 2)
        
        Sizer0.Add(StTxt2,  0, wx.ALL, 2)
        Sizer0.Add(Sizer1, 0, wx.ALL, 2) 
        Sizer0.Add(Sizer2,  0, wx.ALL, 2)
        Sizer0.Add(self.bmpFlag,  0, wx.ALL, 5)

        Pan.SetSizer(Sizer0)
        Sizer0.Fit(self)
        
    def OnPlot(self, event):
        susiki = self.TxtCtl1.GetValue()
        xmin = self.TxtCtl2.GetValue()
        xmax = self.TxtCtl3.GetValue()
        if len(susiki) == 0:   # input error
            self.sb.SetStatusText(u"ERR: 数式が入力されていません.")        
        else:
            xlist = []
            ylist = []
            fxmin = float(xmin)
            fxmax = float(xmax)
            dx = (fxmax-fxmin)/100.
            fig = figure()
            ax = fig.add_subplot(111)
            for i in xrange(101):
                x = fxmin + dx*i
                y = eval(susiki)
                xlist.append(x)
                ylist.append(y)
            ax.plot(xlist, ylist, 'k', color='r', linewidth=2.0)
            ax.autoscale_view()
            xlabel('x')
            ylabel('y')
            title(susiki)
            filen = os.path.join(os.getcwd(), "tempfig")
            fig.savefig(filen)              
                
            bmp = wx.Image("tempfig.png").Scale(500,400).ConvertToBitmap()
            self.bmpFlag.SetBitmap(bmp)
            self.sb.SetStatusText(u"%sが読み込まれました." % susiki)
        
class Application(wx.App):
    def OnInit(self):
        frame = MainFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    import time
    
    app = Application(0)
    print u"info> 起動時刻: %s." % time.ctime(time.time())
    appl_boot_path = os.getcwd()
    print u"info> 起動ディレクトリ: %s." % appl_boot_path
    app.MainLoop()

if __name__ == '__main__':
    main()
#eof