見出し画像

機能追加(2)グラフ

(Python学習初心者の試行錯誤・備忘録です)

学習進捗の「見える化」へ

学習進捗状況について、「レベル0:16個、レベル1:3個・・合計19個」などと、文字でごちゃごちゃ書いてあっても、やる気にはつながらないみたいです。わかりやすい「見える化」のためには、やはり「グラフ」ですよね。以前、グラフの埋め込み関連でmatplotlibの利用を試みた際には「変な問題」が発生していたのですが、

すうちさんにアドバイスいただいて解決できました。

この時の経験を生かし、今回はグラフを組み込もうと思います。

こちらの、bear_montblanc(Be4rR)さんの記事にある「GUIがぼやける現象を防ぐための関数」を書いておくことが重要です。
mvctest_view.pyのクラスの中に関数を押し込むので、変数にself.をつけたり最初ちょっと面倒でした。変更後のmvctest_view.py を書いておきます。

import PySimpleGUI as eg
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np

class View_EG:
    def __init__(self,theme='LightGreen') -> None:
        self.make_dpi_aware()
        self.makemain(theme)

    def make_dpi_aware(self):
        import ctypes
        import platform
        if int(platform.release()) >= 8:
            ctypes.windll.shcore.SetProcessDpiAwareness(True)
        
    # 描画用の関数
    def draw_figure(self, canvas, figure):
        self.figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
        self.figure_canvas_agg.draw()
        self.figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
        return self.figure_canvas_agg

    def makemain(self, theme='LightGreen'):
        #再度呼び出せるようwindowアトリビュートの有無を確認、あったらcloseして再構築
        if hasattr(self,"window"):
            self.window.close()

        self.mytheme = theme
        eg.theme(self.mytheme)
        lfont = ('標楷體', 100) #大きい表示用フォント
        sfont = ('Arial', 50) #小さい表示用フォント
        btfont= ('Arial', 20) #ボタン表示用フォント
        
        #表示サンプル
        myword = '仮置き'; pinyin = 'karioki'
        menu_def = [
            #['ファイル',['読み込み',['CSV::LoadCSV'],  '---', 'Exit']],
            #上の記法はTkEasyGUI用
            ['ファイル',['読み込み',['LoadCSV'],  '---', 'Exit']],
        ]
    #表示テーマ
        themelist=['LightGreen','Black', 'BlueMono', 'BluePurple', 'BrightColors', 'BrownBlue',
                    'Dark', 'Dark2', 'DarkAmber', 'DarkBlack', 'DarkBlack1', 'DarkBlue',
                    'DarkBlue1', 'DarkBlue10', 'DarkBlue11', 'DarkBlue12', 'DarkBlue13', 
                    'DarkBlue14', 'DarkBlue15', 'DarkBlue16', 'DarkBlue17', 'DarkBlue2', 
                    'DarkBlue3', 'DarkBlue4', 'DarkBlue5', 'DarkBlue6', 'DarkBlue7', 
                    'DarkBlue8', 'DarkBlue9', 'DarkBrown', 'DarkBrown1', 'DarkBrown2', 
                    'DarkBrown3', 'DarkBrown4', 'DarkBrown5', 'DarkBrown6', 'DarkBrown7', 
                    'DarkGreen', 'DarkGreen1', 'DarkGreen2', 'DarkGreen3', 'DarkGreen4', 
                    'DarkGreen5', 'DarkGreen6', 'DarkGreen7', 'DarkGrey', 'DarkGrey1', 
                    'DarkGrey10', 'DarkGrey11', 'DarkGrey12', 'DarkGrey13', 'DarkGrey14', 
                    'DarkGrey2', 'DarkGrey3', 'DarkGrey4', 'DarkGrey5', 'DarkGrey6', 
                    'DarkGrey7', 'DarkGrey8', 'DarkGrey9', 'DarkPurple', 'DarkPurple1', 
                    'DarkPurple2', 'DarkPurple3', 'DarkPurple4', 'DarkPurple5', 'DarkPurple6', 
                    'DarkPurple7', 'DarkRed', 'DarkRed1', 'DarkRed2', 'DarkTanBlue', 'DarkTeal', 
                    'DarkTeal1', 'DarkTeal10', 'DarkTeal11', 'DarkTeal12', 'DarkTeal2',
                    'DarkTeal3', 'DarkTeal4', 'DarkTeal5', 'DarkTeal6', 'DarkTeal7', 
                    'DarkTeal8', 'DarkTeal9', 'Default', 'Default1', 'DefaultNoMoreNagging',
                    'Green', 'GreenMono', 'GreenTan', 'HotDogStand', 'Kayak', 'LightBlue',
                    'LightBlue1', 'LightBlue2', 'LightBlue3', 'LightBlue4', 'LightBlue5',
                    'LightBlue6', 'LightBlue7', 'LightBrown', 'LightBrown1', 'LightBrown10',
                    'LightBrown11', 'LightBrown12', 'LightBrown13', 'LightBrown2', 'LightBrown3',
                    'LightBrown4', 'LightBrown5', 'LightBrown6', 'LightBrown7', 'LightBrown8',
                    'LightBrown9', 'LightGray1', 'LightGreen', 'LightGreen1', 'LightGreen10',
                    'LightGreen2', 'LightGreen3', 'LightGreen4', 'LightGreen5', 'LightGreen6',
                    'LightGreen7', 'LightGreen8', 'LightGreen9', 'LightGrey', 'LightGrey1',
                    'LightGrey2', 'LightGrey3', 'LightGrey4', 'LightGrey5', 'LightGrey6', 
                    'LightPurple', 'LightTeal', 'LightYellow', 'Material1', 'Material2', 
                    'NeutralBlue', 'Purple', 'Python', 'Reddit', 'Reds', 'SandyBeach', 
                    'SystemDefault', 'SystemDefault1', 'SystemDefaultForReal', 
                    'Tan', 'TanBlue', 'TealMono', 'Topanga']   

        layout = [
            [eg.Menu(menu_def)],
            [eg.Combo(values=["zh-TW","ja","en-US"],default_value="zh-TW",key="-LANG-"),
             eg.Text("デザインテーマ"),eg.Combo(values=themelist,default_value=self.mytheme,
                                        key="-THEME-",enable_events=True)],
            [eg.Canvas(key='-CANVAS-',size=(800,180))], #グラフ表示の追加
            [eg.Button("発声", font = btfont, key ="-BTN_SPEAK-"),
            eg.Button("連想", font = btfont, key ="-BTN_SHOW_BACK-"),
            eg.Button("覚えた", font = btfont, key ="-BTN_MEMORIZE-"),
            eg.Button("まだ", font = btfont, key ="-BTN_FORGET-")],
            [eg.Text('サマリー仮置き',
            key="-DISP_SUMMARY-",font=('Arial', 15))],
            [eg.Text(myword, font = lfont, key="-DISP_MAIN-")],
            [eg.Text(pinyin, font = sfont, key="-DISP_SUB-")],
        ]
        self.window = eg.Window("単語暗記 for Windows(Python版)", layout=layout, finalize=True)
        self.fig, self.ax = plt.subplots()
        self.fig_agg = self.draw_figure(self.window['-CANVAS-'].TKCanvas, self.fig)
        #self.window = eg.Window("単語暗記 for Windows(Python版)", layout=layout, finalize=True)
    
    def cleargraph(self):
        self.ax.cla()
        self.fig_agg.draw()

    def showgraph(self,L0,L1,L2,L3,total):
        self.cleargraph()
        x = np.array(['L0', "L1", "L2", "L3", "TOTAL"]) # 横軸の値
        y = np.array([L0,L1,L2,L3,total]) # 棒の高さ
        self.ax.barh(x, y, color=["black","red","orange","green", "blue"] )
        self.fig_agg.draw()

これで、メインのコードを実行すると、

グラフがくみ込まれています。データ表示は、ビューの更新にグラフ表示を追加して
(コントローラークラスのメンバ関数:showgraph の処理を追加)

    def refresh_view(self,myview):
        myview.showgraph(self.levelcount[0],self.levelcount[1],self.levelcount[2],\
                                        self.levelcount[3],self.levelcount[4])
        myview.window["-DISP_SUMMARY-"].update("レベル0:{}個 レベル1:{}個 レベル2:{}個 レベル3:{}個 合計 {}個"\
                        .format(self.levelcount[0],self.levelcount[1],self.levelcount[2],\
                                self.levelcount[3],self.levelcount[4]))
        if self.mycards.topcard is not None:
            myview.window["-DISP_MAIN-"].update(self.mycards.topcard['face'])
            myview.window["-DISP_SUB-"].update("")
        else:
            myview.window["-DISP_MAIN-"].update("None")
            myview.window["-DISP_SUB-"].update("None")

これで、グラフに反映されるようになりました。

学習が進むとグラフが更新されます。

このグラフ機能で「やる気」につながりますように。


この記事が気に入ったらサポートをしてみませんか?