Skip to content

Commit a7fc902

Browse files
authored
Merge pull request matplotlib#31471 from QuLogic/doc-anim3d
DOC: Use FuncAnimation in 3D animations
2 parents 55f8de9 + 269853a commit a7fc902

2 files changed

Lines changed: 30 additions & 13 deletions

File tree

galleries/examples/mplot3d/rotate_axes3d_sgskip.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
66
A very simple animation of a rotating 3D plot about all three axes.
77
8-
See :doc:`wire3d_animation_sgskip` for another example of animating a 3D plot.
8+
See :doc:`wire3d_animation` for another example of animating a 3D plot.
99
1010
(This example is skipped when building the documentation gallery because it
1111
intentionally takes a long time to run)
1212
"""
1313

1414
import matplotlib.pyplot as plt
1515

16+
from matplotlib import animation
1617
from mpl_toolkits.mplot3d import axes3d
1718

1819
fig = plt.figure()
@@ -27,8 +28,9 @@
2728
ax.set_ylabel('y')
2829
ax.set_zlabel('z')
2930

31+
3032
# Rotate the axes and update
31-
for angle in range(0, 360*4 + 1):
33+
def animate(angle):
3234
# Normalize the angle to the range [-180, 180] for display
3335
angle_norm = (angle + 180) % 360 - 180
3436

@@ -45,10 +47,12 @@
4547

4648
# Update the axis view and title
4749
ax.view_init(elev, azim, roll)
48-
plt.title('Elevation: %d°, Azimuth: %d°, Roll: %d°' % (elev, azim, roll))
50+
ax.set_title(f'Elevation: {elev}°, Azimuth: {azim}°, Roll: {roll}°')
51+
52+
53+
ani = animation.FuncAnimation(fig, animate, interval=25, frames=360*4)
4954

50-
plt.draw()
51-
plt.pause(.001)
55+
plt.show()
5256

5357
# %%
5458
# .. tags::

galleries/examples/mplot3d/wire3d_animation_sgskip.py renamed to galleries/examples/mplot3d/wire3d_animation.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
===========================
55
66
A very simple "animation" of a 3D plot. See also :doc:`rotate_axes3d_sgskip`.
7-
8-
(This example is skipped when building the documentation gallery because it
9-
intentionally takes a long time to run.)
107
"""
118

129
import time
1310

1411
import matplotlib.pyplot as plt
1512
import numpy as np
1613

14+
from matplotlib import animation
15+
16+
FRAMES = 25
17+
FPS = 25
18+
1719
fig = plt.figure()
1820
ax = fig.add_subplot(projection='3d')
1921

@@ -28,17 +30,28 @@
2830
# Begin plotting.
2931
wframe = None
3032
tstart = time.time()
31-
for phi in np.linspace(0, 180. / np.pi, 100):
32-
# If a line collection is already remove it before drawing.
33+
34+
35+
def animate(i):
36+
global wframe
37+
# If a line collection is already there, remove it before drawing.
3338
if wframe:
3439
wframe.remove()
3540
# Generate data.
41+
phi = i / FRAMES * 2 * np.pi
3642
Z = np.cos(2 * np.pi * X + phi) * (1 - np.hypot(X, Y))
37-
# Plot the new wireframe and pause briefly before continuing.
43+
# Plot the new wireframe.
3844
wframe = ax.plot_wireframe(X, Y, Z, rstride=2, cstride=2)
39-
plt.pause(.001)
45+
if i == FRAMES - 1: # Print FPS at the end of the loop.
46+
global tstart
47+
fps = FRAMES / (time.time() - tstart)
48+
print(f'Expected FPS: {FPS}; Average FPS: {fps}')
49+
tstart = time.time()
50+
51+
52+
ani = animation.FuncAnimation(fig, animate, interval=1000 / FPS, frames=FRAMES)
4053

41-
print('Average FPS: %f' % (100 / (time.time() - tstart)))
54+
plt.show()
4255

4356
# %%
4457
# .. tags::

0 commit comments

Comments
 (0)