Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop FuncAnimation by func in matplotlib?

I write a matplotlib animation program like this:

def animate(frame):
    observation = env.render()
    action = RL.choose_action(str(observation)) # TODO
    action = [random.randint(0, 4) for i in range(ROBOT_NUM)] # TO BE DELETE TODO
    env.step(action)
    observation_ = env.render()
    reward = env.reward
    RL.learn(str(observation), action, reward, str(observation_))  # TODO
    for i in range(TARGET_NUM):
        patchs_target[i].center = (env.targets[i].x, env.targets[i].y)
    for i in range(ROBOT_NUM):
        patchs[i].center = (env.robots[i].x, env.robots[i].y)
        patchs_inner[i].center = (env.robots[i].x, env.robots[i].y)
    return patchs + patchs_inner + patchs_target

.....

anim = animation.FuncAnimation(fig, animate, init_func=init,frames=1, interval=UPDATE_INTERVAL, blit=True)

Now I want to stop animation.FuncAnimation by judge a condition in animate function. Such as if reward < 10 then stop animation.FuncAnimation, but I have no idea how to deal with it.
Or if there are any method to stop animation.FuncAnimation by condition? not by animation times.

like image 763
superDuck Avatar asked Mar 07 '26 21:03

superDuck


1 Answers

Two options:

(1) Using a generator

In order to steer the animation dynamically you may use a generator, which yields new values in a while loop as long some condition is fulfilled. This could look as follows:

reward = 0

def gen():
    global reward
    i = 0
    while reward <= 10:
        i += 1
        yield i

def animate(i):
    global reward
    reward = update(reward)
    some_object[i] = func(reward)
    return some_object

anim = animation.FuncAnimation(fig, animate, frames=gen, repeat = False)

(2) Using a class with event_source.stop().

Alternatively you may stop the animation with anim.event_source.stop(). In order to have access to the animation inside the animating function one may use a class and make the animation a class variable.

class Anim():
    def __init__(self, fig, **kw):
        self.reward=0
        self.ani = animation.FuncAnimation(fig, self.animate, 
                                           frames=100, repeat = False) 

    def animate(self,i):
        reward = update(reward)
        some_object[i] = func(reward)
        if self.reward > 10:
            self.ani.event_source.stop()
        return some_object

Note that both codes are untested because the question does not provide a test case.

like image 90
ImportanceOfBeingErnest Avatar answered Mar 10 '26 16:03

ImportanceOfBeingErnest



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!