Bishara
Bishara

Reputation: 95

matplotlib funcanimation update function is called twice for first argument

Going through some tutorials on matplotlib animations and encountered this problem. I am using the matplotlib.animation funcanimation as follows:

import matplotlib.animation as animation
import numpy as np
from pylab import *

def ani_frame():
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

im = ax.imshow(rand(7, 7), cmap='gray', interpolation='nearest')

tight_layout()

    def update_img(n):
        print(n)
        tmp = rand(7, 7)
        im.set_data(tmp)
        return im

    ani = animation.FuncAnimation(fig, update_img, np.arange(0, 20, 1), interval=200)
    writer = animation.writers['ffmpeg'](fps=5)

    ani.save('demo.mp4', writer=writer)
    return ani

ani_frame()

This generates the following output:

0 0 1 2 3 4 5

and so on. It is calling the first argument twice. How can I prevent this?

Upvotes: 8

Views: 2199

Answers (2)

Purify
Purify

Reputation: 1

If you do not want an empty function in your code, you can use lambda: None function to achieve the same result.

import matplotlib.animation as animation
import numpy as np
from pylab import *

def ani_frame():
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    im = ax.imshow(rand(7, 7), cmap='gray', interpolation='nearest')

    tight_layout()

    def update_img(n):
        print(n)
        tmp = rand(7, 7)
        im.set_data(tmp)

    ani = animation.FuncAnimation(fig, update_img, np.arange(0, 20, 1), 
                                  init_func=lambda: None, interval=200)
    writer = animation.writers['ffmpeg'](fps=5)

    ani.save('demo.mp4', writer=writer)
    return ani

ani_frame()

Upvotes: 0

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339340

You can use an initialization function and provide it to FuncAnimation using the init_func argument. That way the first call will be on the init function and not the update function.

import matplotlib.animation as animation
import numpy as np
from pylab import *

def ani_frame():
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    im = ax.imshow(rand(7, 7), cmap='gray', interpolation='nearest')

    tight_layout()

    def init():
        #do nothing
        pass

    def update_img(n):
        print(n)
        tmp = rand(7, 7)
        im.set_data(tmp)

    ani = animation.FuncAnimation(fig, update_img, np.arange(0, 20, 1),
                                  init_func=init, interval=200)
    writer = animation.writers['ffmpeg'](fps=5)

    ani.save('demo.mp4', writer=writer)
    return ani

ani_frame()

This prints 0 1 2 3 ....

Upvotes: 8

Related Questions