39802


jupyternotebook上で、ループを使ってグラフを描画するときに途中で変数の値(下の例ではb)を変更したいのですができますか？  
途中で値を変えたときにグラフがどのように変化するかをシミュレーションするプログラムを作成中です。  
下記のようにスライダーを使って変更しようとしたら、forループが終了するまでbの値の変更が反映されません。  
また、スライダーを動かした場合、ループ終了後にグラフが消えます。

[code]

    import matplotlib
    %matplotlib inline
    import matplotlib.pyplot as plt
    import time
    from IPython.display import display, clear_output
    from ipywidgets import interact
    
    b=0
    x=[]
    y=[]
    
    def f(a):
        global b
        b=a+1
        print(b)
    
    interact(f,a=(-10,10, 1))
    
    fig = plt.figure()
    axe = fig.add_subplot(111)
    
    for i in range(10):
        x.append(i)
        y.append(i+b)
        axe.plot(x,y)
        display(fig)
        time.sleep(1)
        axe.cla()
        clear_output(wait = True)
    
[/code]

ご教示よろしくお願いします。


CC BY-SA 3.0
2017-11-13T14:19:13.413
39548
2017-11-25T14:04:48.417
21204
question
python jupyter-notebook
forループ中にスライダーの値を反映させたい


載せて頂いたコードの場合、for文が終わるまで関数fが実行されないことが問題かと思います。これを回避するためのコードを書いてみました。

[code]

    %matplotlib notebook 
    import matplotlib.pyplot as plt
    from ipywidgets import interact
    
    b=0
    
    def f(a):
        global b
        b=a+1
        print(b)
    
    interact(f,a=(-10, 10, 1))
    
    # figureとaxesを作成
    fig, axe = plt.subplots()
    
    # 変数の初期化
    idx = 0
    x, y = [], []
    
    # 描画関数
    # def plot_func(timer, fig, axe):
    def plot_func(timer):
        global x, y, b, idx
        global fix, axe
        x.append(idx)
        y.append(idx+b)
        # if idx >= 1:
        if idx >= 10:
            timer.stop()
            return
        axe.plot(x, y)
        axe.set_title('(x, y) = (%d, %d) @index:%d'%(x[-1], y[-1], idx))
        fig.canvas.draw_idle()
    
        idx += 1
    
    # 以前に作成したtimerがあれば削除する
    if 'timer' in locals():
        timer.stop()
        del timer
    
    # 描画更新のトリガーとなるタイマーの作成
    timer = fig.canvas.new_timer(interval=1000)
    # timer.add_callback(plot_func, fig, axe, timer)
    timer.add_callback(plot_func, timer)
    timer.start()
    
    plt.show()
    
[/code]

一行目で

[code]

    %matploblib notebook
    
[/code]

は、Jupyter上でmatplotlibの描画更新のための機能(callback)に必要なmagic
commandです。callback関数(この場合plot_func)内のエラーが発生すると、エラーメッセージが表示されることなく停止する場合があります。このため、デバグが非常にやりにくいので、callback関数の内容変更には十分注意して行ってください。

追記@2017/11/25  
ソースコードを修正しました。


CC BY-SA 3.0
2017-11-24T07:02:07.670
39802
2017-11-25T14:04:48.417
2017-11-25T14:04:48.417
26311
26311
39548
answer