Generate animation of 3D surface plot using plot_surface and animation.ArtistAnimation in Python and matplotlib.pyplot


The result is:

Generate animation of 3D surface plot using plot_surface and animation.ArtistAnimation in Python and matplotlib.pyplot

This page shows how to generate an animation of 3D surface plot using plot_surface and animation.ArtistAnimation in python and matplotlib.pyplot.
See also:

Python Matplotlib Tips: Generate animation of 3D surface plot using plot_surface and animation.FuncAnimation in Python and matplotlib.pyplot

This page shows how to generate an animation of 3D surface plot using plot_surface and animation.Funcanimation in python and matplotlib.pyplot.


This page is refferring the following web page:

The result is quite bad.
Use animation.FuncAnimation function to generate 3D surface plot animation.
The animation.ArtistAnimation is too slow.
The animation is also not shown properly.

In [1]:
import numpy as np
print('numpy: '+np.version.full_version)
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.animation as animation
import matplotlib
print('matplotlib: '+matplotlib.__version__)
numpy: 1.13.3
matplotlib: 2.1.1

Data to show in animation using plot_surface

In [2]:
N = 100 # Meshsize
fps = 10 # frame per sec
frn = 10 # frame number of the animation

x = np.linspace(-4,4,N+1)
x, y = np.meshgrid(x, x)
zarray = np.zeros((N+1, N+1, frn))

f = lambda x,y,sig : 1/np.sqrt(sig)*np.exp(-(x**2+y**2)/sig**2)

for i in range(frn):
    zarray[:,:,i] = f(x,y,1.5+np.sin(i*2*np.pi/frn))

Caution: It takes VERY VERY long time to generate animation using artistanimation under Axes3D.
See the discussion on Github: https://github.com/matplotlib/matplotlib/issues/10207

In [3]:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ims = []
for i in range(frn):
    sf = ax.plot_surface(x, y, zarray[:,:,i], color='0.75', rstride=1, cstride=1)
    ims.append([sf])

ax.set_zlim(0,1.1)
ani = animation.ArtistAnimation(fig, ims, interval=1000/fps, blit=True)

Save the animation in the mp4 and gif format using ffmpeg and imagemagick, respectively.

In [4]:
fn = 'plot_surface_animation_artistanimation'
ani.save(fn+'.mp4',writer='ffmpeg',fps=fps)
ani.save(fn+'.gif',writer='imagemagick',fps=fps)

Reduce the size of the GIF file using imagemagick.

In [5]:
import subprocess
cmd = 'magick convert %s.gif -fuzz 5%% -layers Optimize %s_r.gif'%(fn,fn)
subprocess.check_output(cmd)
Out[5]:
b''

Finaly, show the animation in the jupyter notebook.

As you can see, the resulting animation is not good and not properly shown.

In [6]:
plt.rcParams['animation.html'] = 'html5'
ani
Out[6]: