技術屋にゃん兵衛のてくてくらぼ by データウィズ [DataWith]

気の向くままソフトについて書いてます。バリバリエンジニアではないのであくまでも初心者目線で。

PythonでMathematicaのManipulate関数ライクな実装をする

PythonでMathematicaのManipulate関数ライクな実装をする

 

Wolfram Mathematicaには「Manipulate」という関数があり、パラメーターを変化させたときに、グラフがどのように変わるかをインタラクティブに表示する機能があります。

こういうものね↓

reference.wolfram.com

 

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);

実行すると次のようになります。

ipywidgetsでのスライダーの表示

「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));

実行すると、、、

Playでアニメーション機能を追加した(ボタンが見えない)

ボタンが表示されない。。。ブラウザーのせいかと思って、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では少し行数は増えますが、記述パターンを覚えれば十分に使えそうです。