はじめに
PysimpleGUIでmatplotlibのグラフを表示するには、別Windowで表示する方法、sg.Imageを使う方法、Canvasを使う方法などがあります。それぞれの表示方法を覚えとして記載します。
作成したデモ
(1)別Windowで表示する方法。
参考:PySimpleGUIでMatplotlibのxyグラフを表示する。
(2)sg.Imageを使う方法
sg.Imageでは、png形式のBytesデータ渡さなければなりません。グラフをpngでSaveする際にByteIOを使います。
(3)Canvasを使う方法
Figureをcanvasに紐づけします。
参考:PySimpleGUIにMatplotlibを埋め込みたい
動作環境
Windows10 64bit
Anaconda
python 3.7
VSCode
(1) 別Windowで表示する方法
"""
Matplotlibのグラフを別Winodwで表示
"""
import numpy as np
import matplotlib.pyplot as plt
import PySimpleGUI as sg
def make_data_fig(make=True):
    fig = plt.figure()
    if make:
        # x = np.linspace(0, 2*np.pi, 500)
        x = np.arange(0, 2*np.pi, 0.05*np.pi)
        ax = fig.add_subplot(111)
        ax.plot(x, np.sin(x))
        return fig
    else:
        return fig
def draw_plot(fig):
    
    plt.show(block=False)
    # block=Falseに指定。これが重要
    # コンソールは何も入力を受け付けなくなり、GUI を閉じないと作業復帰できない。
def del_plot(fig):
    
    # plt.cla(): Axesをクリア
    # plt.clf(): figureをクリア
    # plt.close(): プロットを表示するためにポップアップしたウィンドウをクローズ
    
    plt.close()
    
sg.theme('Light Blue 2')
layout = [[sg.Text('Graph Diasplay')],
          [sg.Button('Display',key='-display-'), sg.Button('clear',key='-clear-'), sg.Cancel()]
          ]
window = sg.Window('Plot', layout, location=(100, 100), finalize=True)
while True:
    event, values = window.read()
    if event in (None, 'Cancel'):
        break
    
    elif event == '-display-':
        fig_ = make_data_fig(make=True)
        draw_plot(fig_)
        
    elif event == '-clear-':
        del_plot(fig_)
window.close()
実行例
Displayボタンを押すと別ウインドウでグラフが表示されます。
clearボタンを押すとウインドウが閉じます。
(2) sg.Imageを使う方法
"""
Matplotlibのグラフをsg.Imagenに埋め込む
"""
import io
import numpy as np
import matplotlib.pyplot as plt
import PySimpleGUI as sg
def make_data_fig(make=True):
    fig = plt.figure()
    
    if make:
        # x = np.linspace(0, 2*np.pi, 500)
        x = np.arange(0, 2*np.pi, 0.05*np.pi)
        ax = fig.add_subplot(111)
        ax.plot(x, np.sin(x))
        return fig
    
    else:
        return fig
def draw_plot_image(fig):
    item = io.BytesIO()
    plt.savefig(item, format='png')
    plt.clf()
    # plt.close('all')
    return item.getvalue()
sg.theme('Light Blue 2')
layout = [[sg.Text('Graph Diasplay')],
          [sg.Button('Display',key='-display-'), sg.Button('clear',key='-clear-'), sg.Cancel()],
          [sg.Image(filename='', key='-image-')]
          ]
window = sg.Window('Plot', layout, location=(100, 100), finalize=True)
while True:
    event, values = window.read()
    if event in (None, 'Cancel'):
        break
    
    elif event == '-display-':
        fig_ = make_data_fig()
        fig_bytes = draw_plot_image(fig_)
        window['-image-'].update(data=fig_bytes)
    elif event == '-clear-':
        fig_ = make_data_fig(False)
        fig_bytes = draw_plot_image(fig_)
        window['-image-'].update(data=fig_bytes)
window.close()
実行例
プログラムを実行するとボタン画面が現れます。
Displayボタンを押すとグラフが埋め込まれた表示になります。
clearボタンを押すとグラフが消えます。
(3) Canvasを使う方法
"""
MatplotlibのグラフをCanvasに埋め込む
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import PySimpleGUI as sg
fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(111)
def make_data_fig(fig,make = True):
    
    if make:
        # x = np.linspace(0, 2*np.pi, 500)
        x = np.arange(0, 2*np.pi, 0.05*np.pi)
        ax.plot(x, np.sin(x))
        return fig
    
    else:
        ax.cla()
        return fig
def draw_figure(canvas, figure):
    figure_canvas = FigureCanvasTkAgg(figure, canvas)
    figure_canvas.draw()
    figure_canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
    return figure_canvas
sg.theme('Light Blue 2')
layout = [[sg.Text('Graph Diasplay')],
          [sg.Button('Display',key='-display-'), sg.Button('clear',key='-clear-'), sg.Cancel()],
          [sg.Canvas(key='-CANVAS-')]
          ]
window = sg.Window('Plot', layout, location =(100,100), finalize=True)
# figとCanvasを関連付ける
fig_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig)
while True:
    event, values = window.read()
    if event in (None, 'Cancel'):
        break
    
    elif event == '-display-':
        fig = make_data_fig(fig, make=True)
        fig_agg.draw()
        
    elif event == '-clear-':
        fig = make_data_fig(fig, make=False)
        fig_agg.draw()
window.close()
実行例
プログラムを実行するボタンとグラフ表示画面が現れます。
Displayボタンを押すとグラフがが表示されます。
まとめ
PysimpleGUIでmatplotlibのグラフを表示する3つの方法についてデモを示しました。((1)別Windowで表示する方法、(2)sg.Imageを使う方法、(3)Canvasを使う方法。)
お手軽に表示するには(1)の方法が良いです。 plt.show(block=False)にするのがポイントです。(2)と(3)についてはそれなりに面倒ですが、私は(2)の方が理解しやすいです。png形式に保存する際にio.BytesIO()を使うのがポイントです。






