PySimpleGUI + Matplotlib でパラメータを変更しながらグラフを表示する

# はじめに
 関数からグラフを書く場合、パラメータを変更しながらグラフの様子を見たいことがあります。
例として、下記文献にある、ボールを垂直に投げ上げた時のボール座標の解析解と数値解の比較について、パラメータを変更しながら確認できるようにしました。

[Pythonで学ぶ 流体力学の数値計算法](https://www.ohmsha.co.jp/book/9784274224706/)

ここでは、v0 = 10, 30, 100でのグラフを描写しています。

![スクリーンショット 2020-10-26 112924.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205544/5d38e9d3-a373-27d2-b026-fec64de359c0.jpeg)


## GUI の表示
時間幅：Δt, 初速度：v0, 初期高さ：h0, 重力加速度：gをスライダで変更できるようにします。
スライダで変数を変更後、Submitボタンでグラフを描写、Clearボタンでグラフを削除するようにします。

```python
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()を使用することで、更新可能なグラフを表示させています。


```python

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)