Skip to content

Commit 269853a

Browse files
committed
DOC: Use FuncAnimation in 3D animations
These examples were disabled because the manual pausing caused the example to take very long while the docs were being built. Using the animation framework works if run by itself and also in Sphinx-Gallery, which can then have the frames generated as quickly as possible. That being said, I have only enabled the wire3d animation. The axes3d rotation example goes through so many frames that it takes over 3 minutes, which is by far longer than any other example, so it remains skipped.
1 parent 65e6ba7 commit 269853a

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

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)