数式のグラフ化プログラム(5)
完結編。いただいたコメントをもとにして、2次元プロットと3次元プロットができるようにした。
- 使い方
- xとyの関数形を媒介変数tで表わす。その形を入力する。
- yをxの関数で与える場合にはx=tとしてyをtで表わす。
- 表示するtの範囲(最大値と最小値)と刻み幅を与える。
- 2次元プロットか3次元プロットかをラジオボタンで選ぶ。
- 2次元と3次元の表示例
# coding: utf-8 # ------------------------------------------------------------------- # PlotTool3 ver.1.2 (2008/12/08) # # ------------------------------------------------------------------- import wx import os from pylab import * import matplotlib.axes3d as p3 class MainFrame(wx.Frame): def __init__(self, id, title): width, height = 600, 540 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) Sizer4 = wx.BoxSizer(wx.HORIZONTAL) Pan = wx.Panel(self, -1) StTxt1 = wx.StaticText(Pan, -1, u"xの数式 x=f(t):") StTxt6 = wx.StaticText(Pan, -1, u"yの数式 y=g(t):") self.TxtCtl1 = wx.TextCtrl(Pan, -1, "", size=(300,-1)) self.TxtCtl6 = wx.TextCtrl(Pan, -1, "", size=(300,-1)) self.TxtCtl2 = wx.TextCtrl(Pan, -1, "", size=(60,-1)) self.TxtCtl3 = wx.TextCtrl(Pan, -1, "", size=(60,-1)) self.TxtCtl7 = wx.TextCtrl(Pan, -1, "", size=(60,-1)) StTxt2 = wx.StaticText(Pan, -1, u"【数式の入力はPythonでの記法に従ってください】") BtnPlt = wx.Button(Pan, -1, u"で数式をプロットする") StTxt3 = wx.StaticText(Pan, -1, u"tの表示範囲:") StTxt4 = wx.StaticText(Pan, -1, u"から") StTxt5 = wx.StaticText(Pan, -1, u"までを刻み幅") self.RBtn1 = wx.RadioButton(Pan, -1, "2D", style=wx.RB_GROUP) self.RBtn2 = wx.RadioButton(Pan, -1, "3D") self.RBtn1.SetValue(True) self.fig = figure() bmp = wx.EmptyBitmap(450,350) self.bmpFlag = wx.StaticBitmap(Pan, -1, bmp, (0,0)) # self.bmpFlag.SetBitmap(bmp) BtnPlt.Bind(wx.EVT_BUTTON, self.OnPlot) # self.Bind(wx.EVT_RADIOBUTTON, self.OnRadio) Sizer1.Add(StTxt1, 0, wx.ALL, 2) Sizer1.Add(self.TxtCtl1, 0, wx.ALL, 2) Sizer4.Add(StTxt6, 0, wx.ALL, 2) Sizer4.Add(self.TxtCtl6, 0, wx.ALL, 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) Sizer2.Add(self.TxtCtl7, 0, wx.ALL, 2) Sizer2.Add(self.RBtn1, 0, wx.ALL, 2) Sizer2.Add(self.RBtn2, 0, wx.ALL, 2) Sizer2.Add(BtnPlt, 0, wx.RIGHT, 2) Sizer0.Add(StTxt2, 0, wx.ALL, 2) Sizer0.Add(Sizer1, 0, wx.ALL, 2) Sizer0.Add(Sizer4, 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): susikix = self.TxtCtl1.GetValue() susikiy = self.TxtCtl6.GetValue() tmin = self.TxtCtl2.GetValue() tmax = self.TxtCtl3.GetValue() plot3d = self.RBtn2.GetValue() if len(susikix) == 0 or len(susikiy) == 0: # input error self.sb.SetStatusText(u"ERR: 数式が入力されていません.") else: dt = float(self.TxtCtl7.GetValue()) vtmin = float(tmin) vtmax = float(tmax) vdt = float(dt) t = arange(vtmin, vtmax, vdt) x = eval(susikix) y = eval(susikiy) if plot3d: clf() ax = p3.Axes3D(self.fig) ax.plot3D(x, y, t) else: clf() ax = self.fig.add_subplot(111) ax.plot(x, y, 'k', color='r', linewidth=2.0) ax.autoscale_view() xlabel('x') ylabel('y') tname = susikix + ", "+susikiy title(tname) filen = os.path.join(os.getcwd(), "tempfig") self.fig.savefig(filen, dpi=60) bmp = wx.Bitmap("tempfig.png") self.bmpFlag.SetBitmap(bmp) self.sb.SetStatusText(u"%sと%sが読み込まれました." % (susikix, susikiy)) def OnRadio(self, event): pass 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