I am trying to make an animation with a circle moving in a 3D plot using Matplotlib and FuncAnimation(). Everything works except that I do not find a way to remove the circle already plotted in the previous frame. This leads to the formation of a cylinder as all circles plotted overlap. I only want to plot and see the circle in the current frame. This is the code that I wrote:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import mpl_toolkits.mplot3d.art3d as art3d
from matplotlib.patches import Circle
fig = plt.figure(figsize = (8, 8))
ax = fig.add_subplot(projection="3d")
ax.set_xlabel('X(t)')
ax.set_ylabel('Y(t)')
ax.set_zlabel('Z(t)')
x_min = -100.
x_max = 100.
y_min = -100.
y_max = 100.
z_min = -100.
z_max = 100.
ax.set_xlim3d([x_min, x_max])
ax.set_ylim3d([y_min, y_max])
ax.set_zlim3d([z_min, z_max])
x = 0.
y = 0.
# Center of the circle
center = (x, y)
# Values of z along which the circle will move
z = np.arange(0, 100, 1.)
# Initialize the circle in the 3D plot
def init():
circle = Circle(xy = center, radius = 20., color = "coral")
ax.add_patch(circle)
art3d.pathpatch_2d_to_3d(circle, z = z[0], zdir="z")
return circle
# Animation that changes the z value
def animate(iframe):
circle = Circle(xy = center, radius = 20., color = "coral")
ax.add_patch(circle)
art3d.pathpatch_2d_to_3d(circle, z = z[iframe], zdir="z")
return circle
anim = animation.FuncAnimation(fig, animate, init_func = init, frames=len(z), interval=100, blit=False, repeat = False)
Any idea how to solve this? Thanks.
Update: It works if at the end of animate() one adds:
plt.pause(0.1)
circle.remove()
However, it does not work if plt.pause() is not used. It just does nothing, it does not plot any circle.
Any other solution?
CodePudding user response:
You could use ax.patches.pop()
at the beginning of your animate
function to remove the previous circle (see