tkinterに表示したmatplotlibのグラフを更新する方法

まくまく
まくまく
tkinterのウインドウに表示したグラフを更新する方法です。いろいろと方法はあるようですが、今回はfigやaxesをクリアーする方法を試してみようと思います。



出力


プログラムを実行すると左側にボタン、右側にグラフエリアが表示されます。

ファイル選択ボタンを押して、任意のエクセルファイルを選びます。


エクセルファイルの中身はこんな感じです。B列のデータをグラフ化します。


グラフ描写ボタンを押すと、さきほどのB列のデータがグラフ化されます。


連続して別のエクセルファイルを読み込んで、グラフ描写してみました。うまく更新ができているようです。

グラフの書き換えがうまくできない場合は、軸が追加されたり、複数のグラフが作成されたりします。

今回はあらかじめcanvasを作成しておいて、ボタンを押すことで軸のデータだけを更新するようにしました。

新しいデータを読み込む場合は、41行目「ax.clear()」でデータをクリアしてからあたらしいデータをグラフ化します。42行目から46行目の書き方でも問題なく書き換えできます(細かい違いはありますが見た目上は同じです)。

サンプルプログラム

#ライブラリのインポート
import tkinter as tk
from tkinter import ttk
import tkinter.font
import tkinter.filedialog
import os
import pandas as pd
import math
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        
        #フレーム1作成
        self.frame1 = tk.Frame(self.master, width=200, height=220, padx=10, pady=10, bg="#E6E6E6")
        self.frame1.grid_propagate(False)
        self.frame1.place(x=10, y=10)

        #フレーム2作成
        self.frame2 = tk.Frame(self.master, width=500, height=220, padx=10, pady=10, bg="#E6E6E6")
        self.frame2.grid_propagate(False)
        self.frame2.place(x=220, y=10)

        #ファイル読み込み
        def get_file():
            global df_filename
            f_path = tk.filedialog.askopenfilename(title="ファイル選択", initialdir="")
            df_filename = os.path.basename(f_path) 
            #self.text_filename.set(df_filename)            

        def get_data(self):
            df = pd.read_excel(df_filename, header = 0, index_col = None)
            self.index = df['index']
            self.data = df['data']
        
        def data_to_plt(self):
            ax =self.data.plot.line()
            canvas.draw()
            ax.clear()
            #self.fig.clear()
            #ax.cla()
            #self.fig.clf()
            #plt.cla()
            #plt.clf()
        
        def graph_test():
            get_data(self)
            data_to_plt(self)
        
        #ファイル選択ボタン作成
        button_file_get = ttk.Button(self.frame1, text="ファイル選択", command=get_file)
        button_file_get.grid(row=1, column=0, sticky = tk.W)
        #グラフ描写ボタン作成
        button_recipe_get = ttk.Button(self.frame1, text="グラフ描写", command=graph_test)
        button_recipe_get.grid(row=2, column=0, sticky = tk.W)
        #キャンバス作成
        self.fig = plt.figure(figsize=(3,2))
        canvas = FigureCanvasTkAgg(self.fig, self.frame2)
        canvas.get_tk_widget().pack()


def main():
    def _destroyWindow():
        root.quit()
        root.destroy()

    root = tk.Tk()
    root.geometry("600x240+50+50")
    root.title("graph_test")
    root.protocol('WM_DELETE_WINDOW', _destroyWindow)
    Application(root)

    root.mainloop()

if __name__ == "__main__":
    main()
タイトルとURLをコピーしました