【问题标题】:Inline animations in JupyterJupyter 中的内联动画
【发布时间】:2017-09-12 16:40:33
【问题描述】:

我有一个 python 动画脚本(使用 matplotlib 的 funcAnimation),它在 Spyder 中运行,但不在 Jupyter 中。我尝试了各种建议,例如添加“%matplotlib inline”并将 matplotlib 后端更改为“Qt4agg”,但均未成功。我还尝试过运行几个示例动画(来自 Jupyter 教程),但都没有奏效。有时我会收到一条错误消息,有时情节会出现,但没有动画。顺便说一句,我已经让 pyplot.plot() 使用“%matplotlib inline”工作。

有谁知道有一个使用 funcAnimation 的简单内联动画示例的工作 Jupyter 笔记本。提前感谢您的帮助!

[注意:我使用的是 Windows 7]

【问题讨论】:

    标签: python animation matplotlib jupyter-notebook ipython-notebook


    【解决方案1】:

    笔记本后端

    'Inline' 表示绘图显示为 png 图形。那些 png 图片不能动画化。虽然原则上可以通过连续替换 png 图像来构建动画,但这可能是不希望的。

    一种解决方案是使用笔记本后端,它与FuncAnimation 完全兼容,因为它可以渲染 matplotlib 图形本身:

    %matplotlib notebook
    

    js动画

    从 matplotlib 2.1 开始,我们可以使用 JavaScript 创建动画。这类似于ani.to_html5() 解决方案,只是它不需要任何视频编解码器。

    from IPython.display import HTML
    HTML(ani.to_jshtml())
    

    一些完整的例子:

    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    ax.axis([0,2*np.pi,-1,1])
    l, = ax.plot([],[])
    
    def animate(i):
        l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    from IPython.display import HTML
    HTML(ani.to_jshtml())
    

    或者,将 jsanimation 设置为显示动画的默认设置,

    plt.rcParams["animation.html"] = "jshtml"
    

    然后在最后简单地声明ani来获取动画。

    另请参阅this answer 了解完整概述。

    【讨论】:

    • AttributeError: 'FuncAnimation' 对象没有属性 'to_jshtml'
    • 在 matplotlib 2.1.0 版本中添加了 to_jshtml:matplotlib.org/users/prev_whats_new/whats_new_2.1.0.html!pip install matplotlib --upgrade
    • 当我将示例复制到网络中时,它在我第一次执行时运行良好。第二次返回动画和一个我似乎无法摆脱的空图。它来自哪里?
    • @AliceSchwarze 将plt.close() 放在ani = ... 声明之后以摆脱初始情节。然后第二个ani 启动动画。
    【解决方案2】:

    本教程中有一个简单的示例:http://louistiao.me/posts/notebooks/embedding-matplotlib-animations-in-jupyter-notebooks/

    总结上面的教程,你基本上需要这样的东西:

    from matplotlib import animation
    from IPython.display import HTML
    
    # <insert animation setup code here>
    
    anim = animation.FuncAnimation()  # With arguments of course!
    HTML(anim.to_html5_video())
    

    但是...

    我很难让它发挥作用。本质上,问题在于上述使用(默认情况下)ffmpegx264 在后台编解码器,但这些在我的机器上没有正确配置。解决方案是卸载它们并使用正确的配置从源代码重建它们。有关更多详细信息,请参阅我提出的问题以及 Andrew Heusser 的有效答案:Animations in ipython (jupyter) notebook - ValueError: I/O operation on closed file

    所以,先试试上面的to_html5_video解决方案,如果不行再试试ffmpegx264的卸载/重建。

    【讨论】:

      【解决方案3】:

      另一种选择:

      import matplotlib.animation
      import matplotlib.pyplot as plt
      import numpy as np
      plt.rcParams["animation.html"] = "jshtml"
      plt.rcParams['figure.dpi'] = 150  
      plt.ioff()
      fig, ax = plt.subplots()
      
      x= np.linspace(0,10,100)
      def animate(t):
          plt.cla()
          plt.plot(x-t,x)
          plt.xlim(0,10)
      
      matplotlib.animation.FuncAnimation(fig, animate, frames=10)
      

      【讨论】:

        【解决方案4】:

        这是我从多个来源(包括官方示例)汇总的答案。我使用最新版本的 Jupyter 和 Python 进行了测试。

        import numpy as np
        import matplotlib.pyplot as plt
        import matplotlib.animation as animation
        from IPython.display import HTML
        
        #=========================================
        # Create Fake Images using Numpy 
        # You don't need this in your code as you have your own imageList.
        # This is used as an example.
        
        imageList = []
        x = np.linspace(0, 2 * np.pi, 120)
        y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
        for i in range(60):
            x += np.pi / 15.
            y += np.pi / 20.
            imageList.append(np.sin(x) + np.cos(y))
        
        #=========================================
        # Animate Fake Images (in Jupyter)
        
        def getImageFromList(x):
            return imageList[x]
        
        fig = plt.figure(figsize=(10, 10))
        ims = []
        for i in range(len(imageList)):
            im = plt.imshow(getImageFromList(i), animated=True)
            ims.append([im])
        
        ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000)
        plt.close()
        
        # Show the animation
        HTML(ani.to_html5_video())
        
        #=========================================
        # Save animation as video (if required)
        # ani.save('dynamic_images.mp4')
        

        【讨论】:

          【解决方案5】:

          如果您有一个图像列表并希望通过它们制作动画,您可以使用以下内容:

          from keras.preprocessing.image import load_img, img_to_array
          from matplotlib import animation
          from IPython.display import HTML
          import glob
          
          %matplotlib inline
          
          def plot_images(img_list):
            def init():
              img.set_data(img_list[0])
              return (img,)
          
            def animate(i):
              img.set_data(img_list[i])
              return (img,)
          
            fig = figure()
            ax = fig.gca()
            img = ax.imshow(img_list[0])
            anim = animation.FuncAnimation(fig, animate, init_func=init,
                                           frames=len(img_list), interval=20, blit=True)
            return anim
          
          imgs = [img_to_array(load_img(i)) for i in glob.glob('*.jpg')]
          
          HTML(plot_images(imgs).to_html5_video())
          

          【讨论】:

          • 为了让它工作,你必须下载 ffmpeg 到你的操作系统,然后plt.rcParams['animation.ffmpeg_path'] = '/usr/bin/ffmpeg'。将/usr/bin/ffmpeg' 替换为您操作系统中ffmpeg 二进制文件的路径。
          猜你喜欢
          • 2014-04-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-12
          • 1970-01-01
          • 2021-04-07
          • 2017-10-08
          相关资源
          最近更新 更多