ipywidgets で気楽に条件をいろいろ変えてプロット (インタラクティブなプロット)


パラメタの値などをいろいろ変えたらグラフがどう変わるか見たくなりませんか?パラメタがひとつで取る値が10個というなら、全部プロットできますが、パラメタが2つで100パターン。パラメタが10x10x10で1000パターンとなると静止した図に書き出すのは難しそうです。

ipywidgets を使うとすごく簡単にできます。

$ pip3 install ipywidgets

(Python3 で pip が pip3 という名前の場合。)

Jupyter notebook + matplotlib で、

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from ipywidgets import interact, FloatSlider

x = np.linspace(0, 10, 1000)

@interact(k=(1, 10))
def plot_sin(k):
    plt.plot(x, np.sin(k*x))

と書くと $ \sin kx $ の $k$ の値をスライドバーで変更できます。

二つの値は min, max. 三つ与えると min, max, step になります。

@interact(k=(1.0, 10.0, 0.5))

パラメタが複数あってもこの通り。

@interact(k1=(1, 10), k2=(1, 10))
def plot_sin2(k1, k2):
    plt.plot(x, np.sin(k1*x) + np.sin(k2*x))

初期値

初期値は真ん中になるようで、これを指定したいなら、

@interact(k=FloatSlider(min=0.5, max=5.0, step=0.05, value=1.0))
def plot_sin(k):
    plt.plot(x, np.sin(k*x))

でしょうか。

continious update

スライドするだけで再描画されては重くてかなわんという場合は continuous_update=False を指定するとスライドバーを移動し終わった後に描画されます。

@interact(k=FloatSlider(min=0.5, max=5.0, continuous_update=False))
def plot_sin(k):
    plt.plot(x, np.sin(k*x))

SelectionSlider

等間隔ではなく、不規則な値から選択する場合は。

from ipywidgets import SelectionSlider

@interact(k=SelectionSlider(options=[1.0, 1.1, 2.0], description='k'))
def plot_sin(k):
    plt.plot(x, np.sin(k*x))

ドロップダウンメニューにすることもできます。

参考

先人
https://qiita.com/driller/items/0730325bf5c1cd689979

スライドバー以外にもいろいろあるので、公式ページをみるといろいろ夢が広がります。

https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html
https://ipywidgets.readthedocs.io/en/stable/examples/Widget%20List.html

あくまでも「簡単に」がテーマなので、毎回図をイチから描き直すなどの無駄があります。滑らかさを求めたり、他の人に気持ちよく使って欲しいなどと作り込むなら Bokeh などを使うのが良いかもしれません。その辺は手軽さとのトレードオフになると思います。