Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using matplotlib.animate to animate a contour plot in python

Tags:

I have a 3D array of data (2 spatial dimensions and 1 time dimension) and I'm trying to produce an animated contour plot using matplotlib.animate. I'm using this link as a basis:

http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/

And here's my attempt:

import numpy as np from matplotlib import pyplot as plt from matplotlib import animation from numpy import array, zeros, linspace, meshgrid from boutdata import collect  # First collect data from files n = collect("n")   #  This is a routine to collect data Nx = n.shape[1] Nz = n.shape[2] Ny = n.shape[3] Nt = n.shape[0]  fig = plt.figure() ax = plt.axes(xlim=(0, 200), ylim=(0, 100)) cont, = ax.contourf([], [], [], 500)  # initialisation function def init():     cont.set_data([],[],[])     return cont,  # animation function def animate(i):      x = linspace(0, 200, Nx)     y = linspace(0, 100, Ny)     x,y = meshgrid(x,y)     z = n[i,:,0,:].T     cont.set_data(x,y,z)     return cont,   anim = animation.FuncAnimation(fig, animate, init_func=init,                            frames=200, interval=20, blit=True)  plt.show() 

But when I do this, I get the following error:

Traceback (most recent call last):   File "showdata.py", line 16, in <module>     cont, = ax.contourf([], [], [], 500)   File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 7387, in contourf     return mcontour.QuadContourSet(self, *args, **kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 1112, in __init__     ContourSet.__init__(self, ax, *args, **kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 703, in __init__     self._process_args(*args, **kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 1125, in _process_args     x, y, z = self._contour_args(args, kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 1172, in _contour_args     x,y,z = self._check_xyz(args[:3], kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 1204, in _check_xyz     raise TypeError("Input z must be a 2D array.") TypeError: Input z must be a 2D array. 

So I've tried replacing all the [] by [[],[]] but this then produces:

Traceback (most recent call last):   File "showdata.py", line 16, in <module>     cont, = ax.contourf([[],[]], [[],[]], [[],[]],500)   File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 7387, in contourf     return mcontour.QuadContourSet(self, *args, **kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 1112, in __init__     ContourSet.__init__(self, ax, *args, **kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 703, in __init__     self._process_args(*args, **kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 1125, in _process_args     x, y, z = self._contour_args(args, kwargs)   File "/usr/lib/pymodules/python2.7/matplotlib/contour.py", line 1177, in _contour_args     self.zmax = ma.maximum(z)   File "/usr/lib/python2.7/dist-packages/numpy/ma/core.py", line 5806, in __call__     return self.reduce(a)   File "/usr/lib/python2.7/dist-packages/numpy/ma/core.py", line 5824, in reduce     t = self.ufunc.reduce(target, **kargs) ValueError: zero-size array to maximum.reduce without identity 

Thanks in advance!

like image 915
Luke Avatar asked Jun 04 '13 10:06

Luke


People also ask

How do I use Matplotlib animation?

Animations in Matplotlib can be made by using the Animation class in two ways: By calling a function over and over: It uses a predefined function which when ran again and again creates an animation. By using fixed objects: Some animated artistic objects when combined with others yield an animation scene.

How do you animate in Python?

You can create animations in Python by calling a plot function inside of a loop (usually a for-loop). The main tools for making animations in Python is the matplotlib. animation. Animation base class, which provides a framework around which the animation functionality is built.

What is Matplotlib contour?

MatPlotLib with Python Contour plots (sometimes called Level Plots) are a way to show a three-dimensional surface on a two-dimensional plane. It graphs two predictor variables X Y on the y-axis and a response variable Z as contours. These contours are sometimes called the z-slices or the iso-response values.

How do you plot 3d contour in Python?

ax = plt.axes(projection='3d') # Data for a three-dimensional line zline = np.linspace(0, 15, 1000) xline = np.sin(zline) yline = np.cos(zline) ax.plot3D(xline, yline, zline, 'gray') # Data for three-dimensional scattered points zdata = 15 * np.random.random(100) xdata = np.sin(zdata) + 0.1 * np.random.randn(100) ydata ...


1 Answers

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 plt import numpy import matplotlib.animation as animation #plt.rcParams['animation.ffmpeg_path'] = r"C:\some_path\ffmpeg.exe"   # if necessary  # Generate data for plotting Lx = Ly = 3 Nx = Ny = 11 Nt = 20 x = 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 Gaussian  def 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 screen plt.colorbar()  # animation function def 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 cont  anim = animation.FuncAnimation(fig, animate, frames=Nt, repeat=False) anim.save('animation.mp4', writer=animation.FFMpegWriter()) 
like image 173
plasmo Avatar answered Sep 18 '22 17:09

plasmo