Matplotlib animating multiple lines and text

13,532
def animate(i):
    timetext.set_text(i)
    x = numpy.array(range(1,npdata.shape[0]+1))
    for lnum,line in enumerate(lines):
        line.set_data(x,npdata[:,plotlays[lnum]-1,i])
    return lines, timetext # <- returns a tuple of form (list, artist)

change this to

     return tuple(lines) + (timetext,)

or something similar so that you return an iterable of artists from animate.

Share:
13,532
Admin
Author by

Admin

Updated on July 05, 2022

Comments

  • Admin
    Admin almost 2 years

    Thanks for taking time to read my question, first time I have posted on SO so here goes...

    I am plotting time series data in an animation using matplotlib.animation.FuncAnimation

    I am plotting more than one line by looping over a list and slicing data from a numpy array. This works fine, but I also want to add text to the plot which is animated and describes the frame number.

    I have included sample code below.

    I am trying returning a list of line objects and a text object from the animate function. I receive an attribute error when I try to do this:

    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
        return self.func(*args)
      File "C:\Python27\lib\lib-tk\Tkinter.py", line 531, in callit
        func(*args)
      File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 141, in _on_timer
        TimerBase._on_timer(self)
      File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 1117, in _on_timer
        ret = func(*args, **kwargs)
      File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 773, in _step
        still_going = Animation._step(self, *args)
      File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 632, in _step
        self._draw_next_frame(framedata, self._blit)
      File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 652, in _draw_next_frame
        self._post_draw(framedata, blit)
      File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 675, in _post_draw
        self._blit_draw(self._drawn_artists, self._blit_cache)
      File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 688, in _blit_draw
        if a.axes not in bg_cache:
    AttributeError: 'list' object has no attribute 'axes'
    

    But, say that I have a list of two line objects, if I return the objects individually, e.g.

    return lines[0],lines[1], timetext
    

    I receive no errors.

    Any ideas?

    Cheers Vanessa

    import numpy
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    npdata = numpy.random.randint(100, size=(5,6,10))
    plotlays, plotcols = [2,5], ["black","red"]
    
    fig = plt.figure()
    ax = plt.axes(xlim=(0, numpy.shape(npdata)[0]), ylim=(0, numpy.max(npdata)))
    timetext = ax.text(0.5,50,'')
    
    lines = []
    for index,lay in enumerate(plotlays):
        lobj = ax.plot([],[],lw=2,color=plotcols[index])[0]
        lines.append(lobj)
    
    def init():
        for line in lines:
            line.set_data([],[])
        return lines
    
    def animate(i):
        timetext.set_text(i)
        x = numpy.array(range(1,npdata.shape[0]+1))
        for lnum,line in enumerate(lines):
            line.set_data(x,npdata[:,plotlays[lnum]-1,i])
        return lines, timetext
    
    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=numpy.shape(npdata)[1], interval=100, blit=True)
    
    plt.show()