I'm trying to rotate a 3D cube in matplotlib using FuncAnimation. Instead of just showing a single rendering of a cube that would result in an animation it just paints over itself however, for some kind of 70's fabric art.
After many other false starts this is the closest I got but clearly I'm not using FuncAnimation correctly. I'd be grateful for any hints and explanations where am I going wrong. (This is running in a Jupyter notebook)
%matplotlib notebook
import numpy as np
from numpy import sin, cos, pi
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
rot_num = 1 # number of rotations
smoothness = 90 # how many steps per rotation
# Define corners of a cube
cube = np.array([[0,0,1],[1,0,1],[1,1,1],[0,1,1],[0,0,0],[1,0,0],[1,1,0],[0,1,0]])
angles = np.linspace(0, rot_num*2*pi, smoothness*rot_num)
points = np.zeros(shape=(len(cube), 3, len(angles)), dtype=np.float16)
# Calculate all the points needed for rotation
for i in range(len(points)):
newX = cube[i,0] * cos(angles) - cube[i,2] * sin(angles)
newY = cube[i,1]
newZ = cube[i,2] * cos(angles) + cube[i,0] * sin(angles)
points[i,0] = newX
points[i,1] = newY
points[i,2] = newZ
# Define the vertices/lines of the cube using corners, with color
cube_v = [[points[0], points[1], "green"],
[points[1], points[2], "green"],
[points[2], points[3], "green"],
[points[3], points[0], "green"],
[points[0], points[4], "blue"],
[points[1], points[5], "blue"],
[points[2], points[6], "blue"],
[points[3], points[7], "blue"],
[points[4], points[5], "red"],
[points[5], points[6], "red"],
[points[6], points[7], "red"],
[points[7], points[4], "red"]]
fig = plt.figure()
plt.rcParams["figure.figsize"] = 9,9
ax = fig.add_subplot(111, projection="3d", autoscale_on=True)
ax.grid()
ax.set_title('3D Animation')
ax.set_xlim3d([-2.0, 2.0])
ax.set_xlabel('X')
ax.set_ylim3d([-2.0, 2.0])
ax.set_ylabel('Y')
ax.set_zlim3d([-2.0, 2.0])
ax.set_zlabel('Z')
def update(i):
for vertex in cube_v:
line = ax.plot([vertex[0][0][i], vertex[1][0][i]],
[vertex[0][1][i], vertex[1][1][i]],
[vertex[0][2][i], vertex[1][2][i]],
vertex[2])
ani = animation.FuncAnimation(fig, update, frames=len(angles), interval=20, blit=False, repeat=False)
plt.show()
clear()plot/figure/ax before you create newplot(). Or you have to create/plotlineonly once and later only replacedatain existingline