2017-07-30 10 views
0

matplotlib.animation.FuncAnimationを同じコードで複数回呼び出す方法はありますか?私には、配列が少ないリストがあります。配列にはそれぞれ異なる数の座標が含まれています。私はリストをループし、各配列の点をプロットしてアニメーション化したい。FuncAnimationを複数回使用するにはどうすればいいですか?

これらの2つの異なるシナリオを達成するためにできることはありますか? 1.前のアニメーションの最後のフレームを保持し、その上に新しいアニメーションを開始します。 2.前のアニメーションから最後のフレームを取り除き、新鮮な アニメーションを開始しますが、コードの先頭にバックグラウンドプロットを含めて同じレイアウトを設定してください。

forループでFuncAnimationを使用しようとすると、最初の配列だけがアニメーション化されます。各配列の間には、他にもいくつかの処理が必要なので、forループを取り除き、配列をすべて一緒にアニメーション化することはできません。

import numpy as np 
import matplotlib.animation as animation 
import matplotlib.pyplot as plt 

mylines = [np.array([[1,2], [3,4]]), np.array([[5,6], [7,8], [9,10]])] 

fig, ax = plt.subplots() 

ax.set_xlim([-10, 10]) 
ax.set_ylim([-10, 10]) 

# There's some code here to set the layout (some background plots etc) 
# I omitted it in this question 


def update_plot(i, data, myplot): 
    myplot.set_data(data[:i, 0], data[:i, 1]) 
    return myplot, 

myplot, = ax.plot([], [], '.', markersize=5) 

for k in xrange(len(mylines)): 
    data = mylines[k] 
    numframes = data.shape[0]+1 
    delay = 500 

    ani = animation.FuncAnimation(fig, update_plot, frames=numframes, 
            fargs=(data, myplot), interval=delay, 
            blit=True, repeat=False) 
    plt.show() 


    # Do some more stuff in the for loop here, that's not related to 
    # animations but related to the current array 


    # Then I want to retain the last frame from the animation, and start a new 
    # animation on top of it. Also, what should I do if I want to erase the 
    # last frame instead (erase only the points plotted by the FuncAnimation, 
    # but keep the layout I set at the beginning) 

*編集コードには、いくつかの構文エラーもthis question's solution次試してみました

持っていたので:

ani = [] 

for k in xrange(len(mylines)): 
    data = mylines[k] 
    numframes = data.shape[0]+1 
    delay = 100 

    ani.append(animation.FuncAnimation(fig, update_plot, frames=numframes, 
            fargs=(data, myplot), interval=delay, 
            blit=True, repeat=False)) 
plt.show() 

をしかし、それはいくつかの奇妙なちらつきで、すべてを一度にすべての配列をプロットします。

+0

正確にはアニメーションの目的は何ですか?たぶんあなたは何が起こるべきかを説明することができますか? – ImportanceOfBeingErnest

+0

@ImportanceOfBeingErnest私はそれをもっとはっきり説明することができませんが、私は試してみます: 私はnumpyの配列のリストを持っています(このリストは質問に投稿したコードのmylinesと呼ばれています)。各配列(mylinesリスト内)には、プロットしたい点の座標が含まれています...各配列には異なる数の点があります。リストをループし、各配列の点をプロットしてアニメートしたい(すべてのフレームが新しい点を図に追加する)。 – vegzh

+0

@ImportanceOfBeingErnest私が質問に入力したコードを試してみると、それはmylinesリストの最初の配列のプロットのみをアニメートし、それはただ停止します。ブレークポイントを使用してコードをデバッグしようとしましたが、forループを正常に実行します...ループするたびにFuncAnimationおよびplt.show()が呼び出されていても、次の配列のアニメーションは再生されません。 – vegzh

答えて

0

FuncAnimationをタイマーと考えてください。与えられた引数で指定された速度で関数に渡されます。アニメーションフローを管理するために呼び出される関数を使用すると、それぞれが開始して終了するときに管理する必要がある2つのタイマーを持つのではなく、

import numpy as np 
import matplotlib.animation as animation 
import matplotlib.pyplot as plt 

mylines = [np.array([[1,2], [3,4]]), np.array([[5,6], [7,8], [9,10]])] 

fig, ax = plt.subplots() 

ax.set_xlim([-10, 10]) 
ax.set_ylim([-10, 10]) 

# There's some code here to set the layout (some background plots etc) 
# I omitted it in this question 

myplot, = ax.plot([], [], '.', markersize=5) 


delay = 500 
breaking = 1 

def update_plot(i, data, myplot): 
    myplot.set_data(data[:i, 0], data[:i, 1]) 
    if i == breaking: 
     # do some other stuff 
     print("breaking") 
     myplot.set_color("red") 
    return myplot, 

data = np.append(mylines[0],mylines[1], axis=0) 

ani = animation.FuncAnimation(fig, update_plot, frames=data.shape[0], 
           fargs=(data, myplot), interval=delay, 
           blit=True, repeat=False) 
plt.show() 

これは任意に複雑になることがもちろん:

はたとえば、あなたが何かがアニメーション中に起こるべきでフレーム番号を設定することができます。たとえば、この質問:Managing dynamic plotting in matplotlib Animation moduleを参照してください。ここで、アニメーションの方向はユーザーの入力によって逆になります。ただし、まだ1つのFuncAnimationを使用しています。

関連する問題