####はじめに
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()を使うのがポイントです。