6

I'm looking for a way to update my contour lines in an animation that doesn't require me to replot the figure each time.

Most responses to this question I've found advocate recalling ax.contour, but as my contours are superimposed on another image this is unbearably slow.

The only response I've found that looks close to answering the question answers it with a dead link: Animating a contour plot in matplotlib using FuncAnimation

EDIT: this is probably the intended link.

Example code:

#!/usr/bin/env python

import matplotlib.pylab as plt
import matplotlib.animation as anim
from matplotlib.colors import LinearSegmentedColormap as lsc
import numpy

#fig = 0; ax = 0; im = 0; co = 0


image_data = numpy.random.random((100,50,50))
contour_data = numpy.random.random((100,50,50))

def init():
    global fig, ax, im, co
    fig = plt.figure()
    ax = plt.axes()
    im = ax.imshow(image_data[0,:,:])
    co = ax.contour(contour_data[0,:,:])

def func(n):
    im.set_data(image_data[n,:,:])
    co.set_array(contour_data[n,:,:])

init()
ani = anim.FuncAnimation(fig, func, frames=100)
plt.show()

Cheers.

djvg
  • 11,722
  • 5
  • 72
  • 103
James Jenkinson
  • 1,563
  • 2
  • 16
  • 33

1 Answers1

2

Perhaps you've figured this out by now; unfortunately, it appears that you must re-declare the entire contour/contourf set of artists and remove the old instance at every timestep. Here's some info copied from this link:

The set_array() method (I think) only impacts the colormapping information for contourf, and even then doesn't appear to update. What you need to do is make a new contour plot and remove the old one, especially if you need to change the underlying contoured data. This should be as easy as C.remove(), but for some reason, this doesn't exist (I'll go add it in a minute). So instead, you need to do the following:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.arange(0, 2 * np.pi, 0.1) 
X,Y = np.meshgrid(x,x) 
f1 = np.sin(X) + np.sin(Y) 
f2 = np.cos(X) + np.cos(Y) 

plt.figure() 
C = plt.contourf(f1) 
plt.show() 
for coll in C.collections: 
    plt.gca().collections.remove(coll) 
C = plt.contourf(f2) 
plt.draw() 

This answer is probably what you're looking for.

Luke Davis
  • 2,548
  • 2
  • 21
  • 43