Combining a text update with n curves being updated using matplotlib animation

Question:

I have n curves that I draw using matplotlib’s animation. Thanks to a previous question and the answer to it, this works well. Now I want to add some text in the plot which is continuously updated, basically the frame number, but I have no idea how to combine that object with the iterable of artists my animate function needs to return.

Here is my code:

import matplotlib.animation as anim
import matplotlib.pyplot as plt
import numpy as np

tracks  = {}
xdata   = {}
ydata   = {}

n_tracks    = 2
n_waypts    = 100

for ii in range(n_tracks):
    # generate fake data
    lat_pts = np.linspace(10+ii*1,20+ii*1,n_waypts)
    lon_pts = np.linspace(10+ii*.5,20+ii*.5,n_waypts)

    tracks[str(ii)] = np.array( [lat_pts, lon_pts] )

    xdata[str(ii)]  = []
    ydata[str(ii)]  = []

fig = plt.figure()
ax1 = fig.add_subplot( 1,1,1, aspect='equal', xlim=(0,30), ylim=(0,30) )

plt_tracks  = [ax1.plot([], [], marker=',', linewidth=1)[0] for _ in range(n_tracks)]
plt_lastPos = [ax1.plot([], [], marker='o', linestyle='none')[0] for _ in range(n_tracks)]

plt_text    = ax1.text(25, 25, '')

def animate(i):
    # x and y values to be plotted
    for jj in range(n_tracks):
        xdata[str(jj)].append( tracks[str(jj)][1,i] )
        ydata[str(jj)].append( tracks[str(jj)][0,i] )

    # update x and y data
    for jj in range(n_tracks):
        plt_tracks[jj].set_data(  xdata[str(jj)],  ydata[str(jj)] )
        plt_lastPos[jj].set_data( xdata[str(jj)][-1], ydata[str(jj)][-1] )

    plt_text.set_text('{0}'.format(i))

    return plt_tracks + plt_lastPos 

anim    = anim.FuncAnimation( fig, animate, frames=n_waypts, interval=20, blit=True, repeat=False )
plt.show()

Simply changing the return statement to something like return (plt_tracks + plt_lastPos), plt_text or return (plt_tracks + plt_lastPos), plt_text, does not work. So how do I combine those artists correctly?

Asked By: Alf

||

Answers:

The animate function must return an iterable of artists (where an artist is a thing to draw as a result of a plot-call for example). plt_tracks is such an iterable, as well as plt_lastPost. plt_text, however, is a single artist. A possible solution to make the code work is thus changing the return statement to

return plt_tracks + plt_lastPos + [plt_text]

Alternatively, one could also write

return tuple(plt_tracks + plt_lastPos) + (plt_text,)
Answered By: Alf