Using matplotlib.animate to animate a contour plot in python Using matplotlib.animate to animate a contour plot in python python python

Using matplotlib.animate to animate a contour plot in python


Felix Schneider is correct about the animation becoming very slow. His solution of setting ax.collections = [] removes all old (and superseded) "artist"s. A more surgical approach is to only remove the artists involved in the drawing the contours:

for c in cont.collections:    c.remove()

which is useful in more complicated cases, in lieu of reconstructing the entire figure for each frame. This also works in Rehman Ali's example; instead of clearing the entire figure with clf() the value returned by contourf() is saved and used in the next iteration.

Here is an example code similar to Luke's from Jun 7 '13, demonstrating removing the contours only:

import pylab as pltimport numpyimport matplotlib.animation as animation#plt.rcParams['animation.ffmpeg_path'] = r"C:\some_path\ffmpeg.exe"   # if necessary# Generate data for plottingLx = Ly = 3Nx = Ny = 11Nt = 20x = numpy.linspace(0, Lx, Nx)y = numpy.linspace(0, Ly, Ny)x,y = numpy.meshgrid(x,y)z0 = numpy.exp(-(x-Lx/2)**2-(y-Ly/2)**2)   # 2 dimensional Gaussiandef some_data(i):   # function returns a 2D data array    return z0 * (i/Nt)fig = plt.figure()ax = plt.axes(xlim=(0, Lx), ylim=(0, Ly), xlabel='x', ylabel='y')cvals = numpy.linspace(0,1,Nt+1)      # set contour values cont = plt.contourf(x, y, some_data(0), cvals)    # first image on screenplt.colorbar()# animation functiondef animate(i):    global cont    z = some_data(i)    for c in cont.collections:        c.remove()  # removes only the contours, leaves the rest intact    cont = plt.contourf(x, y, z, cvals)    plt.title('t = %i:  %.2f' % (i,z[5,5]))    return contanim = animation.FuncAnimation(fig, animate, frames=Nt, repeat=False)anim.save('animation.mp4', writer=animation.FFMpegWriter())


This is what I got to work:

# Generate grid for plottingx = linspace(0, Lx, Nx)y = linspace(0, Ly, Ny)x,y = meshgrid(x,y)fig = plt.figure()ax = plt.axes(xlim=(0, Lx), ylim=(0, Ly))  plt.xlabel(r'x')plt.ylabel(r'y')# animation functiondef animate(i):     z = var[i,:,0,:].T    cont = plt.contourf(x, y, z, 25)    if (tslice == 0):        plt.title(r't = %1.2e' % t[i] )    else:        plt.title(r't = %i' % i)    return cont  anim = animation.FuncAnimation(fig, animate, frames=Nt)anim.save('animation.mp4')

I found that removing the blit=0 argument in the FuncAnimation call also helped...


This is the line:

cont, = ax.contourf([], [], [], 500)

change to:

 x = linspace(0, 200, Nx) y = linspace(0, 100, Ny) x, y = meshgrid(x, y) z = n[i,:,0,:].T cont, = ax.contourf(x, y, z, 500)

You need to intilize with sized arrays.