PythonでMathematicaのManipulate関数ライクな実装をする
Wolfram Mathematicaには「Manipulate」という関数があり、パラメーターを変化させたときに、グラフがどのように変わるかをインタラクティブに表示する機能があります。
こういうものね↓
Pythonでも似たような実装ができるので試してみました。
ipywidgets(Jupyter Widgets)に、「interact」という関数があります。これを使うと、UIコントロールを使ってインタラクティブに数値を変えたり、グラフを変更したりできます。
グラフを書く前に、まずは通常の数式を変化させてみます。
ipywidgetsでは、まず、コントロールしたい機能を定義する必要があります。
いつも通り、Google Colaboratoryを使います。簡便に試すには、やはりこれは便利。
from ipywidgets import interact
def func(a, b): return a + b interact(func, a=3, b=5); |
実行すると次のようになります。
「a」と「b」のスライダーを図のように触ると、計算結果が変わります。
これでわかるのは、「a=3」「b=5」というのはデフォルトの値で、値の範囲を示しているわけではないことがわかります。また、スライドバーのステップも指定していません。
範囲やステップを指定するには「IntSlider」を使います。書き方は
[変数]=widgets.IntSlider(min=xxxxx. max=yyyyy, step=zzzzz, value=xyzxyz) |
です。valueのところが最初のコードで使ったデフォルト値です。
では、実際に先ほどのコードを変えてみます。
import ipywidgets as widgets from ipywidgets import interact
def func(a, b): return a + b interact(func, a=widgets.IntSlider(min=-3, max=3, step=1, value=1), b=widgets.IntSlider(min=-5, max=5, step=1, value=0)); |
「import ipywidgets as widgets」を追加するのをお忘れなく。
実行すると次の通り。
きっちり動きますね。
スライダーを手で動かすのではく、プレイボタンでアニメーションのようにするには、「widgets.Play」を使います。「a」だけを砕石できるようにするには、次のような感じ。
import ipywidgets as widgets from ipywidgets import interact
def func(a, b): return a + b interact(func, a=widgets.Play(min=0, max=10), b=widgets.IntSlider(min=-5, max=5, step=1, value=0)); |
実行すると、、、
ボタンが表示されない。。。ブラウザーのせいかと思って、ChromeからEdgeに変えてみても結果は同じ。
4つボタンがあって、左から、「再生」「一時停止」「停止」「繰り返し」のはずなんですが。
Google Colabだからダメなのかもしれないです。
基本は押さえたので、グラフでスライダーを実装します。ボタンがうまく見えないので、見えるようになるまでアニメーションはパスすることにしました。
正弦関数をプロットして、波長を変えられるようにします。
コードは次のような感じ。
「freq」をスライダーで可変にします。
import numpy as np import matplotlib.pyplot as plt from ipywidgets import interact
def plot_function(freq): x = np.linspace(-10, 10, 1000) y = np.sin(freq * x)
plt.plot(x, y) plt.grid(True) plt.show()
interact(plot_function, freq=(0, 10, 1)) |
実行すると次のようになります。
「freq」のスライダーを動かすと、グラフの周波数が変わります。
MathematicaのManipulateだと1行なので、Pythonでは少し行数は増えますが、記述パターンを覚えれば十分に使えそうです。