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


The result is:

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.
See also:

Python Matplotlib Tips: Rotate azimuth angle and animate 3d plot_surface using Python and matplotlib.pyplot

This page shows how to generate animation with rotating azimuth angle in the 3D surface plot using python, matplotlib.pyplot, and matplotlib.animation.FuncAnimation.

Python Matplotlib Tips: Rotate elevation angle and animate 3d plot_surface using Python and matplotlib.pyplot

This page shows how to generate animation with rotating elevation angle in the 3D surface plot using python, matplotlib.pyplot, and matplotlib.animation.FuncAnimation.


This page is refferring the following web page:

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 = 150 # Meshsize
fps = 10 # frame per sec
frn = 50 # 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))

In order to animate the 3D surface graph, animation.FuncAnimation is suitable. This is because the animation.Artistanimation takes VERY LONG TIME to generate 3D animations. See the discussion in Github: https://github.com/matplotlib/matplotlib/issues/10207

In [3]:
def update_plot(frame_number, zarray, plot):
    plot[0].remove()
    plot[0] = ax.plot_surface(x, y, zarray[:,:,frame_number], cmap="magma")

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

plot = [ax.plot_surface(x, y, zarray[:,:,0], color='0.75', rstride=1, cstride=1)]
ax.set_zlim(0,1.1)
ani = animation.FuncAnimation(fig, update_plot, frn, fargs=(zarray, plot), interval=1000/fps)

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

In [4]:
fn = 'plot_surface_animation_funcanimation'
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.

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