Removing duplicates from animation's lened of a 3d plot in python
Question:
I am exporting an animation in python but the legend is repeating. I have only one plot and want to have one single legend item in every frame of the animation. This is my script:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
x = np.linspace(0., 10., 100)
y = np.linspace(0., 10., 100)
z = np.random.rand(100)
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot (111, projection="3d")
def init():
# Plot the surface.
ax.scatter3D(x, y, z, label='random', s=10)
ax.set_zlabel('Z [m]')
ax.set_ylabel('Y [m]')
ax.set_xlabel('X [m]')
plt.legend()
ax.grid(None)
return fig,
def animate(i):
ax.view_init(elev=20, azim=i)
return fig,
# Animate
ani = animation.FuncAnimation(fig, animate, init_func=init,
frames=360, interval=200, blit=True)
# Export
ani.save('random data.gif', writer='pillow', fps=30, dpi=50)
And this is the animation in which legend is repeated three times:
I very much appreciate any help.
Answers:
As was suggested here, replace plt.legend()
with the following 3 lines:
def init():
# Plot the surface.
ax.scatter3D(x, y, z, label='not random', s=10)
ax.set_zlabel('Z [m]')
ax.set_ylabel('Y [m]')
ax.set_xlabel('X [m]')
# REPLACE plt.legend() STARTS HERE
handles, labels = plt.gca().get_legend_handles_labels()
by_label = dict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())
# REPLACE plt.legend() ENDS HERE
ax.grid(None)
return fig,
The issue is that init
is called multiple times, You should avoid creating the graph in this function.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
x = np.linspace(0., 10., 100)
y = np.linspace(0., 10., 100)
z = np.random.rand(100)
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot (111, projection="3d")
# Plot the surface.
ax.scatter3D(x, y, z, label='random', s=10)
ax.set_zlabel('Z [m]')
ax.set_ylabel('Y [m]')
ax.set_xlabel('X [m]')
plt.legend()
ax.grid(None)
def init():
return fig,
def animate(i):
ax.view_init(elev=20, azim=i)
return fig,
# Animate
ani = animation.FuncAnimation(fig, animate, init_func=init,
frames=360, interval=200, blit=True)
# Export
ani.save('random data.gif', writer='pillow', fps=30, dpi=50)
Output:
I am exporting an animation in python but the legend is repeating. I have only one plot and want to have one single legend item in every frame of the animation. This is my script:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
x = np.linspace(0., 10., 100)
y = np.linspace(0., 10., 100)
z = np.random.rand(100)
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot (111, projection="3d")
def init():
# Plot the surface.
ax.scatter3D(x, y, z, label='random', s=10)
ax.set_zlabel('Z [m]')
ax.set_ylabel('Y [m]')
ax.set_xlabel('X [m]')
plt.legend()
ax.grid(None)
return fig,
def animate(i):
ax.view_init(elev=20, azim=i)
return fig,
# Animate
ani = animation.FuncAnimation(fig, animate, init_func=init,
frames=360, interval=200, blit=True)
# Export
ani.save('random data.gif', writer='pillow', fps=30, dpi=50)
And this is the animation in which legend is repeated three times:
I very much appreciate any help.
As was suggested here, replace plt.legend()
with the following 3 lines:
def init():
# Plot the surface.
ax.scatter3D(x, y, z, label='not random', s=10)
ax.set_zlabel('Z [m]')
ax.set_ylabel('Y [m]')
ax.set_xlabel('X [m]')
# REPLACE plt.legend() STARTS HERE
handles, labels = plt.gca().get_legend_handles_labels()
by_label = dict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())
# REPLACE plt.legend() ENDS HERE
ax.grid(None)
return fig,
The issue is that init
is called multiple times, You should avoid creating the graph in this function.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
x = np.linspace(0., 10., 100)
y = np.linspace(0., 10., 100)
z = np.random.rand(100)
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot (111, projection="3d")
# Plot the surface.
ax.scatter3D(x, y, z, label='random', s=10)
ax.set_zlabel('Z [m]')
ax.set_ylabel('Y [m]')
ax.set_xlabel('X [m]')
plt.legend()
ax.grid(None)
def init():
return fig,
def animate(i):
ax.view_init(elev=20, azim=i)
return fig,
# Animate
ani = animation.FuncAnimation(fig, animate, init_func=init,
frames=360, interval=200, blit=True)
# Export
ani.save('random data.gif', writer='pillow', fps=30, dpi=50)
Output: