【问题标题】:Animation in iPython notebookiPython 笔记本中的动画
【发布时间】:2016-06-02 15:09:08
【问题描述】:

我正在尝试将动画放在 iPython 笔记本中,但没有找到解决方案。我看到一篇讨论使用交互式小部件的帖子,但是我遇到了几个问题:首先,我看到的每个小部件示例都使用滑块或其他输入,而我只希望动画在单元格时自动运行正在运行。其次,Jupyter 网站上的所有文档似乎都过时了——每当我下载并运行他们的笔记本时,我都会收到这些关于某些模块被弃用的消息,然后在文件中某些东西无法运行,大概是因为他们正在尝试导入和访问不再存在的文件。

我看过一些关于该主题的其他页面,但它们通常需要下载二进制文件或其他模块,但我部分使用它来教一些学生数学,我让他们下载 Anaconda——我希望不要让他们同时下载和安装更复杂的东西,同时花时间不谈论数学,从而进一步混淆问题。

简而言之,有没有一种方法可以让我在 iPython 笔记本中创建动画,只需要使用简单的导入命令,这些命令将开箱即用,可以说来自 Anaconda 的软件?

[编辑:我还应该注意,我使用 Tkinter 制作动画,我敢肯定,我可以在 matplotlib 中制作动画。因此,如果有一种方法可以让您制作的动画与在 iPython 笔记本中呈现的动画一起呈现,那对我来说肯定是一个可行的解决方案。]

[进一步编辑:我想我也可以说出我现在希望制作动画的内容,尽管如果我决定制作动画,我真的很想灵活处理我可以制作动画的范围。现在,我正在尝试制作一个数字时钟,以 Sumerian base-60 数字显示每个数字,以说明不同的计数和基本系统。所以它最初应该显示 |然后一秒钟后||以此类推,直到 10 被表示为

[未来人类注意事项:如果您正在实施一些动画并愿意公开托管它,请在 cmets 中留下指向它的链接!我很好奇现在人们是如何制作动画的,也有点好奇他们在制作什么动画。]

【问题讨论】:

  • JSAnimation,但需要额外安装。您可以用IPython.display.clear_output 替换诸如绘图之类的输出,但它不够平滑,无法正确设置动画。
  • JSAnimation 不再需要额外安装。自 2.1 版以来,它已被合并到 matplotlib 中。用法显示在@ImportanceOfBeingErnest 回答的最后一个 sn-p 中。

标签: python-3.x animation ipython jupyter-notebook


【解决方案1】:

You may find this tutorial interesting.

如果你能把你需要的东西变成一个 matplotlib 动画,而且我从你的描述中相当确定这是可能的,那么你就可以使用

from matplotlib import rc, animation
rc('animation', html='html5')

并使用

显示您的动画
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=N, interval=20, blit=True)
anim

可能会派上用场!

【讨论】:

  • 为什么这个 sn-p 会显示两个“窗口”,一个是空白的,另一个是带有视频的?
【解决方案2】:

我遇到了类似的问题,这个问题帮助我入门。我整理了一个说明使用 FuncAnimation 的笔记本,并很好地解释了为什么笔记本会以它的方式执行某些操作。它还具有指向 FFmpeg 说明的链接。它还包含指向我在开发和理解动画时使用的示例的链接。您可以在以下位置查看我的贡献: Animation Illustration

对于您的问题,您可能会发现交互式滑块是一种更好的工具。我还创建了一个在 Jupyter 中演示交互式小部件的笔记本。可用here;但是,交互部分在那里不起作用。

两者都可以通过GitHub Repostory 获得

【讨论】:

    【解决方案3】:

    Jupyter 小部件是显示动画的好方法。下面的代码显示了一个动画 gif .....

    from ipywidgets import Image
    from IPython import display
    animatedGif = "animatedGifs/01-progress.gif" #path relative to your notebook
    file = open(animatedGif , "rb")
    image = file.read()
    progress= Image(
        value=image,
        format='gif',
        width=100,
        height=100)
    display.display(progress)
    

    您可以使用以下方法关闭此动画:

    progress.close()
    

    注意我从http://www.downgraf.com/inspiration/25-beautiful-loading-bar-design-examples-gif-animated/ 中找到了一些不错的动画 gif。

    【讨论】:

      【解决方案4】:

      在 Jupyter/IPython 中使用 matplotlib 动画绘图的一些选项:

      • 在循环中使用display 使用IPython.display.display(fig) 在输出中显示一个数字。使用循环,您可能希望在显示新图形之前清除输出。请注意,这种技术通常不会给出那么平滑的结果。因此,我建议使用以下任何一种。

        import matplotlib.pyplot as plt
        import matplotlib.animation
        import numpy as np
        from IPython.display import display, clear_output
        
        t = np.linspace(0,2*np.pi)
        x = np.sin(t)
        
        fig, ax = plt.subplots()
        l, = ax.plot([0,2*np.pi],[-1,1])
        
        animate = lambda i: l.set_data(t[:i], x[:i])
        
        for i in range(len(x)):
            animate(i)
            clear_output(wait=True)
            display(fig)
            
        plt.show()
      • %matplotlib notebook 使用 IPython 魔术%matplotlib notebook 将后端设置为笔记本后端。这将使图形保持活动状态,而不是显示静态 png 文件,因此还可以显示动画。
        完整示例:

        %matplotlib notebook
        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()
        l, = ax.plot([0,2*np.pi],[-1,1])
        
        animate = lambda i: l.set_data(t[:i], x[:i])
        
        ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
        
        plt.show()
      • %matplotlib tk 使用 IPython 魔术%matplotlib tk 将后端设置为 tk 后端。这将在一个新的绘图窗口中打开图形,该窗口是交互式的,因此也可以显示动画。
        完整示例:

        %matplotlib tk
        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()
        l, = ax.plot([0,2*np.pi],[-1,1])
        
        animate = lambda i: l.set_data(t[:i], x[:i])
        
        ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
        
        plt.show()
      • 将动画转换为 mp4 视频(@Perfi 已经提到的选项):

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

        或在笔记本的开头使用plt.rcParams["animation.html"] = "html5"。 这将需要 ffmpeg 视频编解码器可用于转换为 HTML5 视频。然后内嵌显示视频。因此,这与%matplotlib inline 后端兼容。完整示例:

        %matplotlib inline
        import matplotlib.pyplot as plt
        plt.rcParams["animation.html"] = "html5"
        import matplotlib.animation
        import numpy as np
        
        t = np.linspace(0,2*np.pi)
        x = np.sin(t)
        
        fig, ax = plt.subplots()
        l, = ax.plot([0,2*np.pi],[-1,1])
        
        animate = lambda i: l.set_data(t[:i], x[:i])
        
        ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
        ani
        %matplotlib inline
        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()
        l, = ax.plot([0,2*np.pi],[-1,1])
        
        animate = lambda 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_html5_video())
      • 将动画转换为 JavaScript

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

        或在笔记本的开头使用plt.rcParams["animation.html"] = "jshtml"。 这会将动画显示为带有 JavaScript 的 HTML。这与大多数新浏览器以及%matplotlib inline 后端高度兼容。它在 matplotlib 2.1 或更高版本中可用。
        完整示例:

        %matplotlib inline
        import matplotlib.pyplot as plt
        plt.rcParams["animation.html"] = "jshtml"
        import matplotlib.animation
        import numpy as np
        
        t = np.linspace(0,2*np.pi)
        x = np.sin(t)
        
        fig, ax = plt.subplots()
        l, = ax.plot([0,2*np.pi],[-1,1])
        
        animate = lambda i: l.set_data(t[:i], x[:i])
        
        ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
        ani
        %matplotlib inline
        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()
        l, = ax.plot([0,2*np.pi],[-1,1])
        
        animate = lambda 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())

      【讨论】:

      • 快速提问,因为我根本不懂这些后端的东西,你会建议如何学习它们?有没有我可以查阅的书或一些一般主题,以便研究理解它们所必需的东西?或者也许是一个更好的问题:如果您参加 CompSci 课程,您会在哪节课上学习这些?
      • 我对 CompSci 课程一无所知。我猜你是通过使用它们来了解它们的。有一个关于他们的matplotlib page。关于 Jupyter,有 this page 作为介绍。
      • 在 matplotlib 中将动画转换为 JavaScript 是一个福音,尤其是因为它消除了为匆忙的人安装 ffmpeg 编解码器的麻烦。 @ImportanceOfBeingErnest 在答案中很好地使用了代码 sn-ps。我可以知道将代码作为 CSS 放在答案中是经过深思熟虑的选择,还是对于 HTML/JS 等是否相同?我必须承认,我花了几分钟的时间只是单击 Run code snippet 期望看到一些 python 输出。
      • @Harsh 很抱歉造成混乱。我滥用这个 css/javascrip 特性来隐藏代码,以免弄乱答案。这样可以清楚地看到答案中的所有选项,但同时为任何需要它的人提供了一个完整的示例(我总是喜欢提供 mcves 以使某些命令明确。)不幸的是,此“隐藏代码”功能不可用对于其他语言,如 python。
      • 上面的第一个(慢)方法对于在线动画非常有用,即,当您逐帧生成数据时,而不是所有先验。
      猜你喜欢
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 2014-09-14
      • 2014-09-16
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多