matplotlibはpythonでグラフを描画する人気ライブラリです。
今回は、「matplotlibをGUI化してさらに便利にする」ことを実施します。
この記事では、
- グラフ描画にGUIを使うメリット
- tkinterとmatplotlibの連携方法
をつかんでいただけたらと思います。
サンプルでは三角関数(\(\sin\)、\(\cos\)、\(\tan\))を描画するプログラムを書いていきます。
MatplotlibでGUIを使うメリット
まずは、Matplitlibを使ってみましょう。
まずはMatplotlibを使ってみる
matplotlibのインストールは、PIPコマンドで下記のようにインストールできます。
pip install matplotlib
⇒「Successfully installed~」がでればOK
次のsin関数を使った式を描画してみましょう。
$$y=A\sin \omega x + B$$
ただし、 \( A \) 、\( \omega \)、\(B\)は適当な定数とします。
import matplotlib.pyplot as plt import numpy as np fig,ax = plt.subplots() # Figure, Axesを作成 x = np.arange(-5, 5, 0.01) # -5から5まで0.01刻みでXを作成 A = 2 omega = 1 B = 2 y = A * np.sin(omega * x) + B # 全てのxについてyの値をsin関数で計算 ax.plot(x, y) # グラフにx,yをプロット plt.show() # グラフの可視化
下記のとおり、sin関数が表示されたかと思います。
GUIをつけるメリット
上記のようにMatplotlibを使うことで、簡単にグラフを描画できました。
しかし、下記のような場合には、ソースコードを書き換えるため少し手間になります。
- 定数の部分(\( A \) 、\( \omega \)、\(B\))を変える場合
- \(\sin\)ではなくて\(\cos\)や\(\tan\)を使いたい場合
tkinterとmatplotlibでグラフ描画アプリを作る
開発環境
- OS Windows 10
- Pythonバージョン 3.7.1
- ライブラリ tkinter、matplotlib
サンプルプログラム 三角関数のグラフ描画アプリ
import tkinter as tk from tkinter import ttk import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import numpy as np #ファイルのプロット処理 class c_inputData(ttk.Frame): def __init__(self, inputFrame): tk.Label(inputFrame, text = "f(t)=").pack(side=tk.LEFT) self.editBoxA = tk.Entry(inputFrame, width=5) self.editBoxA.pack(side=tk.LEFT) self.editBoxA.insert(tk.END, 1) self.trgFunc = tk.StringVar() self.ComboboxTrgFunc = ttk.Combobox(inputFrame, textvariable=self.trgFunc, width=3) self.ComboboxTrgFunc['values'] = ("sin", "cos", "tan") self.ComboboxTrgFunc.insert(tk.END, "sin") self.ComboboxTrgFunc.pack(side=tk.LEFT) tk.Label(inputFrame, text="(").pack(side=tk.LEFT) self.editBoxOmega = tk.Entry(inputFrame, width=5) self.editBoxOmega.pack(side=tk.LEFT) self.editBoxOmega.insert(tk.END, 1) tk.Label(inputFrame, text="t)+").pack(side=tk.LEFT) self.editBoxB = tk.Entry(inputFrame, width=5) self.editBoxB.pack(side=tk.LEFT) self.editBoxB.insert(tk.END, 0) def plot_sct(self, canvas, ax): A = float(self.editBoxA.get()) B = float(self.editBoxB.get()) omega = float(self.editBoxOmega.get()) ax.cla() #前の描画データの削除 x = np.arange(-5, 5, 0.01) trg = self.ComboboxTrgFunc.get() if trg == "sin": y = A * np.sin(omega * x) + B elif trg == "cos": y = A * np.cos(omega * x) + B else: y = A * np.tan(omega * x) + B ax.set_ylim([-30, 30]) ax.grid() ax.plot(x, y) #グラフの描画 canvas.draw() #Canvasを更新 if __name__ == "__main__": ### rootオブジェクト生成 ### root = tk.Tk() root.title("三角関数の描画アプリ") ### フレームの作成 ### inputFrame = ttk.Frame(root) # 入力エリア buttonFrame = ttk.Frame(root) # ボタンを表示するエリア graphFrame = ttk.Frame(root) # グラフを描画するエリア ### inputFrame ### inputData = c_inputData(inputFrame) inputFrame.pack() ### buttonFrame ### #Plotボタン ButtonWidth = 15 UpdateButton = tk.Button(buttonFrame, text="Plot", width=ButtonWidth, \ command = lambda:inputData.plot_sct(Canvas, ax)) UpdateButton.grid(row = 0, column = 0) buttonFrame.pack() #グラフの初期化 fig,ax = plt.subplots() Canvas = FigureCanvasTkAgg(fig, master = graphFrame) #Canvasにfigを追加 Canvas.get_tk_widget().pack() graphFrame.pack() #描画を継続 root.mainloop()
サンプルプログラムの簡単な解説
今回の記事のメインとなるmatplotlibとtkinterを連携は下記ように実施しています。
- matplotlibのFigure, Axes作成(Figureの変数名:fig、Axesの変数名:ax) 70行目
- figを引数で指定して「FigureCanvasTkAgg」ウィジェットを作成 71行目
※ここでfigとウィジェットが紐づけ - ウィジェットを配置 72~73行目
- axに値をプロット 43行目
- Canvasを更新 44行目
この①、②、③は一度やってしまえばOKのため、メインプログラムで1度しか呼ばれていません。
一方④と⑤はグラフを逐次更新する処理のため、ボタンを押すごとに呼ばれています。
(ボタンと描画処理の関連付けは64~65行目です)
ウィジェットの配置方法が不明な方は、下記をご参考にしてください。
【Python】tkinterのWidgetの配置方法【サンプルプログラムで解説】
実行結果
1.初期画面
2.\(\sin\)を設定して「Plot」ボタンを押下
3.\(\cos\)を設定して「Plot」ボタンを押下
4.\(\tan\)を設定して「Plot」ボタンを押下
まとめ
この記事では、「グラフ描画にGUIを使うメリット」「matplotlibとtkinterの連携方法」についてご紹介させていただきました。
サンプルでは、tkinterとmatplotlibを使って三角関数を描画するGUIアプリを作成しました。
プログラムの応用としては、
- プロットするX、Yの範囲をGUIから読み込めるようにする
- GUIで指定したファイルを読み込んでプロットできるようにする
- グラフの色や線の種類をGUIから選択できるようにする
など沢山のアイデアが考えられます。