pythonmatplotlibanimationplotlegend

How to add legend on matplotlib animations?


I have a animation of an orbit written in python. I want a legend that the label is a time "dt". This time updates (increases) along the orbit. For example, in the first frame of the gif the legend should be "dt", in the second, dt + dt and so on. I tried something that didn't work. Maybe I'm not using the correct commands. The error that appearas: TypeError: __init__() got multiple values for argument 'frames' . Does someone know how to do this legend? The code is above.

fig = plt.figure()

plt.xlabel("x (km)")
plt.ylabel("y (km)")
plt.gca().set_aspect('equal')
ax = plt.axes()
ax.set_facecolor("black")
circle = Circle((0, 0), rs_sun, color='dimgrey')
plt.gca().add_patch(circle)
plt.axis([-(rs_sun / 2.0) / u1 , (rs_sun / 2.0) / u1 , -(rs_sun / 2.0) / u1 , (rs_sun / 2.0) / u1 ])

# Legend

dt = 0.01

leg = [ax.plot(loc = 2, prop={'size':6})]

def update(dt):
  for i in range(len(x)):
    lab = 'Time:'+str(dt+dt*i)
    leg[i].set_text(lab)
  return leg

# GIF

graph, = plt.plot([], [], color="gold", markersize=3)
    
plt.close() 

def animate(i):
    graph.set_data(x[:i], y[:i])
    return graph,

skipframes = int(len(x)/500)
if skipframes == 0:
    skipframes = 1

ani = FuncAnimation(fig, update, animate, frames=range(0,len(x),skipframes), interval=20)

Solution

  • To update the labels in your legend you can use:

    graph, = plt.plot([], [], color="gold",lw=5,markersize=3,label='Time: 0')
    L=plt.legend(loc=1)
    L.get_texts()[0].set_text(lab)
    

    L.get_texts()[0].set_text(lab) should be called inside the update function to refresh the label at each iteration of the animation.

    You can find a minimal example below to illustrate the process:

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    fig,ax = plt.subplots()
    dt = 0.01
    N_frames=30
    x=np.random.choice(100,size=N_frames,) #Create random trajectory
    y=np.random.choice(100,size=N_frames,) #Create random trajectory
    graph, = plt.plot([], [], color="gold",lw=5,markersize=3,label='Time: 0')
    L=plt.legend(loc=1) #Define legend objects
    
    def init():
        ax.set_xlim(0, 100)
        ax.set_ylim(0, 100)
        return graph,
    
    def animate(i):
        lab = 'Time:'+str(round(dt+dt*i,2))
        graph.set_data(x[:i], y[:i])
        L.get_texts()[0].set_text(lab) #Update label each at frame
    
        return graph,
    
    ani = animation.FuncAnimation(fig,animate,frames=np.arange(N_frames),init_func=init,interval=200)
    plt.show()
    

    And the output gives:

    enter image description here