0

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?

Alf
  • 1,821
  • 3
  • 30
  • 48
  • Which IDE are you using? Your code ran perfectly when I copied it into Jupyter Notebook (and added `%matplotlib notebook` to the top). – trent Nov 01 '22 at 10:52
  • @trent yes, it runs fine, indeed. But there is no `plt_text` included in the return statement at the moment, so the text is not updated. To answer your question: I am running the code directly from the command line using Ubuntu 20.04.4 – Alf Nov 04 '22 at 09:37
  • The text IS updated in Jupyter Notebook. The frame number is displayed as the animation runs. You could try to update the frame number inside animate without an artist. To do that, put `ax1.text(25, 25, str(i))` in place of `plt_text.set_text('{0}'.format(i))` – trent Nov 04 '22 at 22:51

1 Answers1

0

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,)
Alf
  • 1,821
  • 3
  • 30
  • 48