Matplotlib动画保持静态

时间:2016-12-07 22:58:05

标签: python animation matplotlib

以下代码在jupyter笔记本中运行,它给我一个静态图像:

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()

输出如下:

enter image description here

为什么会这样?此外,当我删除“%matplotlib nbagg”时,我收到一条错误消息:

---------------------------------------------------------------------------
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 个答案:

答案 0 :(得分:1)

免责声明:此答案解决了代码本身的问题,并允许将其作为python脚本运行。它确实无法解决在jupyter笔记本中设置动画的问题。 (见评论)

两件事:

  1. 您需要在init函数中为图像设置一些数据。
  2. init()以及update()的返回必须是元组,如果您想使用blit=True(否则您甚至不需要返回)。由于您只想对图像本身进行blit,因此可以将return im,与逗号一起使用。
  3. 完整的运行代码:

    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()