はじめに
関数からグラフを書く場合、パラメータを変更しながらグラフの様子を見たいことがあります。
例として、下記文献にある、ボールを垂直に投げ上げた時のボール座標の解析解と数値解の比較について、パラメータを変更しながら確認できるようにしました。
ここでは、v0 = 10, 30, 100でのグラフを描写しています。
GUI の表示
時間幅:Δt, 初速度:v0, 初期高さ:h0, 重力加速度:gをスライダで変更できるようにします。
スライダで変数を変更後、Submitボタンでグラフを描写、Clearボタンでグラフを削除するようにします。
import numpy as np
from matplotlib import pyplot as plt
import PySimpleGUI as sg
layout = [
[
sg.Text(
'delta t',
size=(13, 1)
),
sg.Slider(
(0.01, 1),
0.1,
0.01,
orientation='h',
size=(15, 15),
key='-DELTA T-',
enable_events=True
)
],
[
sg.Text(
'v0',
size=(13, 1)
),
sg.Slider(
(0.01, 100),
10,
0.1,
orientation='h',
size=(15, 15),
key='-V0-',
enable_events=True
)
],
[
sg.Text(
'h0',
size=(13, 1)
),
sg.Slider(
(0, 100),
0,
1,
orientation='h',
size=(15, 15),
key='-H0-',
enable_events=True
)
],
[
sg.Text(
'gravity',
size=(13, 1)
),
sg.Slider(
(0.1, 100),
9.8,
0.1,
orientation='h',
size=(15, 15),
key='-G-',
enable_events=True
)
],
[
sg.Button(
'Submit',
size=(10, 1)
),
sg.Button(
'Clear',
size=(10, 1)
)
]
]
window = sg.Window('Trajectory of ball', layout, location=(0, 0))
グラフの表示
matplotlibでグラフを表示します。plt.figureとfig.add_subplot()でグラフ領域を作成したのち、メインループを回します。
GUIのイベントを監視し、submitボタンを押すと、スライダから値を読み取り、グラフを表示するようにしています。また、plt.pause()を使用することで、更新可能なグラフを表示させています。
fig = plt.figure(figsize=(7, 7), dpi=100)
ax = fig.add_subplot(111)
while True:
event, values = window.read(timeout=0)
if event == "__TIMEOUT__":
continue
# Exitボタンが押されたら、またはウィンドウの閉じるボタンが押されたら終了
elif event in ('Exit', sg.WIN_CLOSED, None):
break
elif event == 'Submit':
dt = values['-DELTA T-']
v0 = values['-V0-']
g = values['-G-']
h0 = values['-H0-']
t1 = ((v0 ** 2 + 2 * g * h0) ** 0.5 + v0) / g
t = np.linspace(0, t1, 100)
h = -0.5 * g * t ** 2 + v0 * t + h0
la, = plt.plot(t, h, color='blue')
# ##########################################################
t = 0
h = h0
# h = 0まで描写に変更
while h >= 0:
ln = plt.scatter(t, h, marker='o', c='black')
h += (-g * t + v0) * dt
t += dt
# グラフの描写
ax.set_xlabel('Time')
ax.set_ylabel('Height')
ax.grid(color='black', linestyle='dashed', linewidth=0.5)
ax.legend(handles=[la, ln], labels=['Analytical', 'Numerical'])
plt.pause(0.1)
# ##########################################################
elif event == 'Clear':
plt.clf()
ax = fig.add_subplot(111)
plt.pause(0.1)