【Python】tkinterとmatplotlibでグラフ描画アプリを作る ※サンプルプログラムあり


管理人
グラフ描画GUI作ります!

matplotlibはpythonでグラフを描画する人気ライブラリです。

 

今回は、「matplotlibをGUI化してさらに便利にする」ことを実施します。

 

この記事では、

  • グラフ描画にGUIを使うメリット
  • tkinterとmatplotlibの連携方法

をつかんでいただけたらと思います。

 

サンプルでは三角関数(\(\sin\)、\(\cos\)、\(\tan\))を描画するプログラムを書いていきます。

 


MatplotlibでGUIを使うメリット

まずは、Matplitlibを使ってみましょう。

まずはMatplotlibを使ってみる

matplotlibのインストールは、PIPコマンドで下記のようにインストールできます。

pip install matplotlib
⇒「Successfully installed~」がでればOK

 

管理人
さっそくmatplotlibを使ってみましょう!

次の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\)を使いたい場合

 

piyo
そこでGUIの出番ですね!

 

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を連携は下記ように実施しています。

  1. matplotlibのFigure, Axes作成(Figureの変数名:fig、Axesの変数名:ax) 70行目
  2. figを引数で指定して「FigureCanvasTkAgg」ウィジェットを作成 71行目
    ※ここでfigとウィジェットが紐づけ
  3. ウィジェットを配置 72~73行目
  4. axに値をプロット 43行目
  5. Canvasを更新 44行目

 

この①、②、③は一度やってしまえばOKのため、メインプログラムで1度しか呼ばれていません。

一方④と⑤はグラフを逐次更新する処理のため、ボタンを押すごとに呼ばれています
(ボタンと描画処理の関連付けは64~65行目です)

 

ウィジェットの配置方法が不明な方は、下記をご参考にしてください。

【Python】tkinterのWidgetの配置方法【サンプルプログラムで解説】

実行結果

1.初期画面

 

2.\(\sin\)を設定して「Plot」ボタンを押下

 

3.\(\cos\)を設定して「Plot」ボタンを押下

 

4.\(\tan\)を設定して「Plot」ボタンを押下

 

管理人
パラメータを変えた通りに動きましたね!
piyo
いろんなバリエーションで試すときはGUIが便利ですね

 

 

まとめ

この記事では、「グラフ描画にGUIを使うメリット」「matplotlibとtkinterの連携方法」についてご紹介させていただきました。

 

サンプルでは、tkinterとmatplotlibを使って三角関数を描画するGUIアプリを作成しました。

 

プログラムの応用としては、

  • プロットするX、Yの範囲をGUIから読み込めるようにする
  • GUIで指定したファイルを読み込んでプロットできるようにする
  • グラフの色や線の種類をGUIから選択できるようにする

など沢山のアイデアが考えられます

 

管理人
matplotlibをよく使う方も、ぜひ活用してみてください