2017-01-26 25 views
2

私は、既存のmatplotlib FuncAnimationの間隔を変更する方法があるかどうかを判断しようとしています。ユーザーの入力に応じてアニメーションの速度を調整できるようにしたい。以前に作成したmatplotlib FuncAnimationの間隔を変更することはできますか?

私は同様の質問How do I change the interval between frames (python)?を見つけましたが、答えが得られなかったので、私はとにかく尋ねると思っていました。

私が必要と持っているものの最低限の例は次のとおりです。私はこの問題にコメントし解決策を持っている変速機能で

""" 
Based on Matplotlib Animation Example 

author: Jake Vanderplas 
https://stackoverflow.com/questions/35658472/animating-a-moving-dot 
""" 
from matplotlib import pyplot as plt 
from matplotlib import animation 
import Tkinter as tk 
import numpy as np 

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg 


class AnimationWindow(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 

     self.fig = plt.figure(0, figsize=(10, 10)) 

     self.anim = None 

     self.speed = 2 

     self.canvas = FigureCanvasTkAgg(self.fig, self) 
     self.canvas.show() 
     self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True) 
     self.canvas.mpl_connect('resize_event', self.on_resize) 

     self.bar = tk.Scale(self, from_=0.25, to=10, resolution=0.25, command=self.change_play_speed, orient=tk.HORIZONTAL) 
     self.bar.pack(fill=tk.X) 

    def start_animation(self): 
     ax = plt.axes() 

     self.x = np.arange(0, 2 * np.pi, 0.01) 
     self.line, = ax.plot(self.x, np.sin(self.x)) 

     # The return needs to be assigned to a variable in order to prevent the cleaning by the GC 
     self.anim = animation.FuncAnimation(self.fig, self.animation_update, frames=100, 
              interval=100/self.speed, blit=True, repeat=False) 

    def animation_update(self, i): 
     self.line.set_ydata(np.sin(self.x + i/10.0)) # update the data 
     return self.line, 

     return tuple(self.annotation) 

    def change_play_speed(self, speed): 
     self.speed = float(speed) 

     # This works but I think somehow the previous animation remains 
     #self.anim = animation.FuncAnimation(self.fig, self.animation_update, frames=100, interval=100/self.speed, blit=True, repeat=False) 

    def on_resize(self, event): 
     """This function runs when the window is resized. 
     It's used to clear the previous points from the animation which remain after resizing the windows.""" 

     plt.cla() 


def main(): 
    root = tk.Tk() 

    rw = AnimationWindow(root) 
    rw.pack() 

    rw.start_animation() 

    root.mainloop() 

if __name__ == '__main__': 
    main() 

。この解決策には2つの主要な問題があります。それは非常に非効率的です(私は思っています)。以前のアニメーションを削除してちらつきの原因となる方法を見つけられませんでした。

答えて

1

私はアニメーションを削除するよう勧めません。より複雑なアニメーションの1つの選択肢は、もちろんそれらを手動でプログラムすることです。 update関数を繰り返し呼び出すタイマーを使用すると、実際にはFuncAnimationを作成するよりもはるかに多くのコードが使用されます。

しかし、この場合、解決策は非常に簡単です。 event_sourceの間隔を変更する:

def change_play_speed(self, speed): 
    self.speed = float(speed) 
    self.anim.event_source.interval = 100./self.speed 
関連する問題