0

The following code, which is run in the jupyter notebook, is giving me a static image:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
%matplotlib nbagg

mat = np.random.random((1000, 50, 50))

def quick_play(dT = 10):
    fig, ax = plt.subplots()
    im = ax.imshow(mat[0], cmap = "gray")

    def init():
        im.set_data([])
        return im

    def animate(i):
        im.set_data(mat[i])
        return im

    ani = animation.FuncAnimation(fig, animate, frames = 100, init_func = init, interval = dT, blit = True)
    plt.show()

quick_play()

The output looks like this:

enter image description here

Why is this occuring? Furthermore, when I remove the "%matplotlib nbagg", I get an error message:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-728862430f94> in <module>()
     20     plt.show()
     21 
---> 22 quick_play()

<ipython-input-1-728862430f94> in quick_play(dT)
     17         return im
     18 
---> 19     ani = animation.FuncAnimation(fig, animate, frames = 100, init_func = init, interval = dT, blit = True)
     20     plt.show()
     21 

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\animation.py in __init__(self, fig, func, frames, init_func, fargs, save_count, **kwargs)
   1191         self._save_seq = []
   1192 
-> 1193         TimedAnimation.__init__(self, fig, **kwargs)
   1194 
   1195         # Need to reset the saved seq, since right now it will contain data

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\animation.py in __init__(self, fig, interval, repeat_delay, repeat, event_source, *args, **kwargs)
   1035 
   1036         Animation.__init__(self, fig, event_source=event_source,
-> 1037                            *args, **kwargs)
   1038 
   1039     def _step(self, *args):

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\animation.py in __init__(self, fig, event_source, blit)
    647                                                       self._stop)
    648         if self._blit:
--> 649             self._setup_blit()
    650 
    651     def _start(self, *args):

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\animation.py in _setup_blit(self)
    933         self._resize_id = self._fig.canvas.mpl_connect('resize_event',
    934                                                        self._handle_resize)
--> 935         self._post_draw(None, self._blit)
    936 
    937     def _handle_resize(self, *args):

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\animation.py in _post_draw(self, framedata, blit)
    898             self._blit_draw(self._drawn_artists, self._blit_cache)
    899         else:
--> 900             self._fig.canvas.draw_idle()
    901 
    902     # The rest of the code in this class is to facilitate easy blitting

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\backend_bases.py in draw_idle(self, *args, **kwargs)
   2024         if not self._is_idle_drawing:
   2025             with self._idle_draw_cntx():
-> 2026                 self.draw(*args, **kwargs)
   2027 
   2028     def draw_cursor(self, event):

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py in draw(self)
    472 
    473         try:
--> 474             self.figure.draw(self.renderer)
    475         finally:
    476             RendererAgg.lock.release()

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     60     def draw_wrapper(artist, renderer, *args, **kwargs):
     61         before(artist, renderer)
---> 62         draw(artist, renderer, *args, **kwargs)
     63         after(artist, renderer)
     64 

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\figure.py in draw(self, renderer)
   1163 
   1164         self._cachedRenderer = renderer
-> 1165         self.canvas.draw_event(renderer)
   1166 
   1167     def draw_artist(self, a):

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\backend_bases.py in draw_event(self, renderer)
   1807         s = 'draw_event'
   1808         event = DrawEvent(s, self, renderer)
-> 1809         self.callbacks.process(s, event)
   1810 
   1811     def resize_event(self):

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\cbook.py in process(self, s, *args, **kwargs)
    561             for cid, proxy in list(six.iteritems(self.callbacks[s])):
    562                 try:
--> 563                     proxy(*args, **kwargs)
    564                 except ReferenceError:
    565                     self._remove_proxy(proxy)

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\cbook.py in __call__(self, *args, **kwargs)
    428             mtd = self.func
    429         # invoke the callable and return the result
--> 430         return mtd(*args, **kwargs)
    431 
    432     def __eq__(self, other):

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\animation.py in _start(self, *args)
    659 
    660         # Now do any initial draw
--> 661         self._init_draw()
    662 
    663         # Add our callback for stepping the animation and

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\animation.py in _init_draw(self)
   1222 
   1223         else:
-> 1224             self._drawn_artists = self._init_func()
   1225             if self._blit:
   1226                 if self._drawn_artists is None:

<ipython-input-1-728862430f94> in init()
     10 
     11     def init():
---> 12         im.set_data([])
     13         return im
     14 

C:\Users\Alexander\Anaconda3\lib\site-packages\matplotlib\image.py in set_data(self, A)
    451         if (self._A.ndim not in (2, 3) or
    452                 (self._A.ndim == 3 and self._A.shape[-1] not in (3, 4))):
--> 453             raise TypeError("Invalid dimensions for image data")
    454 
    455         self._imcache = None

TypeError: Invalid dimensions for image data

1 Answer 1

1

Disclaimer: This answer solves the problems in the code itself and allows to run it as python script. It does not solve the problem of animating it in a jupyter notebook. (see comments)

Two things:

  1. You need to set some data to the image in the init function.
  2. The return of init() as well as update() must be a tuple, if you want to use blit=True (otherwise you don't even need a return). Since you only want to blit the image itself, you can use return im, with the comma.

Complete running code:

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


mat = np.random.random((1000, 50, 50))
print mat[0].shape
def quick_play(dT = 10):
    fig, ax = plt.subplots()
    im = ax.imshow(mat[0], cmap = "gray")

    def init():
        im.set_data(mat[0])
        return im,

    def animate(i):
        im.set_data(mat[i])
        return im,

    ani = animation.FuncAnimation(fig, animate, frames = 100, init_func = init, interval = dT, blit = True)
    plt.show()

quick_play()
Sign up to request clarification or add additional context in comments.

3 Comments

Hmm strange it's working inside a python script but not inside the jupyter notebook. Do you know why this might be?
Are animations supposed to run inside jupyter at all? I'm really not an expert on jupyter so it may well be. On the other hand, there are some more or less complicated hacks around to make animations work in jupyter (see here, or here which were obsolete if it was working out of the box.
This site should be of great help to you. It seems animations work with some backends and not with others, also depending on the operating system. That said I just became aware that the above code solved a problem that you haven't actually been aware of existing at all. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.