Leonardo
Leonardo

Reputation: 5

Animation with matplotlib and numpy

I'm in doubt about what is the difference among the codes below. I'm using matplotlib's animation class to render numpy's arrays. In the atualizaMundo() function, if I use mundo[:] = new_mundo[:] it works just fine, but if I use mundo=new_mundo the arrays get equal but the animation doesn't work. What is the difference here?

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

ON = 255
OFF = 0

def criaMundo(N):
    return(np.random.choice([ON,OFF],N*N,p=[0.5,0.5]).reshape(N,N))


def atualizaMundo(frameNum,N,mundo,img):
    new_mundo = np.random.choice([ON,OFF],N*N,p=[0.5,0.5]).reshape(N,N)
    img.set_data(mundo)
    mundo[:]=new_mundo[:]
    #mundo=new_mundo
    return(img,)

def main():
    try:        
        N = 4
        mundo = criaMundo(N)
        print(mundo)
        fig1,ax = plt.subplots()
        img = ax.imshow(mundo)
        animacao = animation.FuncAnimation(fig1, atualizaMundo, fargs=(N,mundo,img,), blit=True)
        plt.show()
    except Exception as ex:
        pass

if __name__ == '__main__':
    try:
        main()
    except Exception as fk:
        pass

Upvotes: 0

Views: 621

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339122

The line mundo[:]=new_mundo[:] modifies the existing array mundo. You're therefore always operating on the same object and changes made to it are reflected in the animation. Next time the function is called by the animation the same object is passed as argument so the changes made in the previous call are preserved. Note that mundo[:]=new_mundo[:] is equivalent to mundo[:]=new_mundo.

Opposed to that mundo=new_mundo assigns the new array to a local variable called mundo, which replaces the passed argument mundo. However, it is only of local scope and once the function finishes, the changed mundo is simply not present anymore. In the next call to the function, the old and unchanged mundo is passed again to the function, leading to a static animation.

It should be noted that you don't actually need to pass mundo at all in this case, as you could simply set the newly calculated array new_mundo directly to the image: img.set_data(new_mundo).

Upvotes: 1

Related Questions