iPython 笔记本中的动画

Animation in iPython notebook

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

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

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

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

[进一步编辑:我想我现在也可以说出我希望制作动画的内容,尽管如果我决定的话,我真的想对可以制作动画的东西的范围非常灵活。现在我正在尝试制作一个数字时钟,它以苏美尔 base-60 数字显示每个数字,以说明不同的计数和基本系统。所以它应该最初显示 |然后在一秒钟后 ||依此类推,直到十被表示为 < 等等,直到最终时钟滴答到一分钟,现在显示 |:|代表一分一秒。]

[未来人类请注意:如果您正在实现某些动画并愿意公开托管它,请在评论中留下 link!我很好奇现在人们是如何制作动画的,也有点想知道他们在制作什么动画。]

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

可能会派上用场!

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

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

两者都可用 GitHub Repostory

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

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

在 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使用IPythonmagic%matplotlib notebook设置后台为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使用IPythonmagic%matplotlib tk设置后台为tk后台。这将在新的绘图 window 中打开图形,它是交互式的,因此也可以显示动画。
    完整示例:

    %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"。 这会将动画显示为 HTML 和 JavaScript。这与大多数新浏览器以及 %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())