【Python】【Tkinter】【Matplotlib】GUIアプリにMatplotlibを組み込む

matplotlib,python,tkinter

はじめに

Pythonの標準ライブラリであるTkinterを使うと、GUIアプリを作成できます。このGUIアプリにMatplotlibのグラフを組み込む必要があったため、組み込み方を調べてみました。そのメモです。

ウィンドウの生成

ルートウィンドウの生成

まずはTkinterでルートウィンドウを生成します。ルートウィンドウの生成のほかに、ウィンドウサイズやウィンドウのタイトルも設定します。

import tkinter as tk

root = tk.Tk()
root.geometry("640x480")
root.title("Tkinter x Matplotlib test")

フレームの生成と配置

ルートウィンドウにフレームを配置します。このフレームの中にMatplotlibのグラフを含め、ウィジェットを配置します。

frame = tk.Frame(root)
frame.pack(expand=True, fill=tk.BOTH)

配置はpack()を使って、ルートウィンドウ全体に広げます。これには、expandfillを指定する必要があります。expandTrueにすることで初期配置でフレームをルートウィンドウ全体に広げます。filltk.BOTHを指定すると、ウィンドウサイズを変更したときに、フレームをルートウィンドウ全体に広げることができます。

Matplotlibのグラフの作成

通常と同じようにMatplotlibのグラフを作成します。データをグラフに与えることも可能ですが、plt.show()は行いません。

from matplotlib import pyplot as plt

figure = plt.Figure()
ax = figure.add_subplot(111)

Matplotlibのグラフの配置

作成したグラフをフレームに配置します。MatplotlibにはグラフをTkinterで扱えるようにするための、FigureCanvasTkAggというクラスがありますので、これを使用します。

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

canvas = FigureCanvasTkAgg(figure=figure, master=frame)
canvas.get_tk_widget().pack(expand=True, fill=tk.BOTH)

FigureCanvasTkAggをつかって、フレームの子ウィンドウとしてキャンバスを生成し、Matplotlibで作成した図figureを結びつけます。キャンバスに対してget_tk_widget()を使うと、Tkinterのウィジェットとして扱えるようになるので、pack()でフレームに配置します。このとき、expandfillを指定することで、フレームに対して全面に表示することが可能です。

配置にはpack()だけではなく、grid()place()も使えます。

メインループの実行

メインループを実行し、ユーザーからの入力を待ちます。

root.mainloop()

実際の例

MatplotlibとTkinterを組み合わせた実際の例を以下に示します。このコードは、ルートウィンドウにフレームを1つ作成し、フレーム中にはMatplotlibのグラフとボタンを1つ配置しています。ボタンを押すたびに、ランダムに100点(x, y)の組を生成し、グラフにプロットします。

import random
import tkinter as tk
from matplotlib import pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

def generate_xy():
    """ランダムに100点生成する"""
    x = []
    y = []

    for i in range(0, 100):
        x.append(random.random())
        y.append(random.random())

    return (x, y)

def on_click():
    """ボタンをクリックしたときに新たに100点生成する"""
    x, y = generate_xy()
    ax.clear()
    ax.scatter(x, y)
    figure.canvas.draw()

root = tk.Tk()
root.geometry("640x480")
root.title("Tkinter x Matplotlib test")

frame = tk.Frame(root)
frame.pack(expand=True, fill=tk.BOTH)

button = tk.Button(frame, text="show", command=on_click)
button.pack(side="bottom")

x, y = generate_xy()

figure = plt.Figure()
ax = figure.add_subplot(111)
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.scatter(x, y)

canvas = FigureCanvasTkAgg(figure=figure, master=frame)
canvas.get_tk_widget().pack(expand=True, fill=tk.BOTH)

root.mainloop()

まとめ

Tkinterを使用したGUIアプリにMatplotlibのグラフを組み込む方法を調べてみました。

  1. 通常と同じようにMatplotlibのグラフを作成する
  2. FigureCanvasTkAggクラスを使って、作成したグラフを結びつけたウィンドウを作成する
  3. 作成したウィンドウに対してget_tk_widget()を使い、ウィジェットを取得する
  4. pack()等を使って親ウィンドウに配置する

matplotlib,python,tkinter

Posted by izadori