【问题标题】:Matplotlib animation not working in IPython Notebook (blank plot)Matplotlib 动画在 IPython Notebook 中不起作用(空白图)
【发布时间】:2014-10-09 14:54:01
【问题描述】:

我尝试了多个动画示例代码,但其中任何一个都无法正常工作。这是我从 Matplotlib 文档中尝试过的一个基本方法:

"""
A simple example of an animated plot
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig, ax = plt.subplots()

x = np.arange(0, 2*np.pi, 0.01)        # x-array
line, = ax.plot(x, np.sin(x))

def animate(i):
    line.set_ydata(np.sin(x+i/10.0))  # update the data
    return line,

#Init only required for blitting to give a clean slate.
def init():
    line.set_ydata(np.ma.array(x, mask=True))
    return line,

ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init,
    interval=25, blit=True)
plt.show()

当我在 IPython Notebook 中执行上述操作时,我只看到生成了一个空白图。我已经尝试使用多个浏览器(Chrome、FF、IE)从多台服务器(包括 Wakari)、多台机器上运行它。

我可以将动画保存为 mp4 文件,播放时看起来不错。

感谢任何帮助!

【问题讨论】:

  • 在不使用内嵌图形的情况下运行它。

标签: matplotlib ipython-notebook


【解决方案1】:

总结您的选择:

  • 在循环中使用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 视频

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

【讨论】:

  • 感谢您的总结。这正是我想要的!两个 cmets:(a) 从 matplotlib 2.1.0 开始,我想应该是 ani.to_html5_video() 而不是 ani.to_html5(); (b) @Perfi 是谁?我在此页面上看不到他撰写的答案或 cmets。
  • 一个有点深奥的提示:在我意识到 %matplotlib inline%matplotlib notebook 之间存在冲突之前,我在使用此选项时遇到了麻烦。我需要删除%matplotlib inline 并运行%matplotlib notebook 两次,如下所述:github.com/ipython/ipython/issues/10873
  • @atkat12 是的,如果你想中途更改后端,这似乎是我也found here的解决方案。
【解决方案2】:

根据这个answer,您可以在IPython notebook 中获得动画(和完整的交互支持),通过%matplotlib nbagg 启用nbagg 后端。

【讨论】:

    【解决方案3】:

    直到刚才我还遇到了和你一样的问题。我是一个完全的新手,所以 tcaswell 的回答对我来说有点神秘。也许你明白了他的意思或找到了你自己的解决方案。如果你还没有,我会把它放在这里。

    我搜索了“matplotlib 内联数字”并找到了this 站点,其中提到您必须启用 matplotlib 模式。不幸的是,仅仅使用%maplotlib 根本没有帮助。

    然后我在云雀上的 IPython 控制台中输入了%matplotlib qt,它现在工作得很好,尽管绘图出现在一个单独的窗口中。

    【讨论】:

      【解决方案4】:

      我也遇到了这个问题,发现我需要了解 matplotlib 后端的概念,如何启用特定的后端,以及哪些后端与 FuncAnimation 一起使用。我整理了一个ipython notebook,它解释了细节并总结了哪些后端可以在 Mac、Windows 和 wakari.io 上使用 FuncAnimation。该笔记本还总结了哪些后端与 ipython interact() 小部件一起使用,以及基本 matplotlib 绘图的绘图出现在哪里(内联或辅助窗口)。包含代码和说明,因此您可以重现任何结果。

      最重要的是,您无法让使用 FuncAnimation 创建的动画在 ipython 笔记本中内联显示。但是,您可以让它显示在单独的窗口中。事实证明,我需要这个来为我本学期教的本科班创建可视化,虽然我更喜欢内联动画,但至少我能够创建一些有用的可视化来在课堂上展示。

      【讨论】:

        【解决方案5】:

        动画结束时Jupyter中没有内嵌视频也会发生

        HTML(ani.to_html5_video())

        不在笔记本单元格的最后,因为输出会被抑制。

        你可以按如下方式使用它

        out = HTML(ani.to_html5_video())

        只需在新单元格中输入`即可在线获取视频。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-06
          • 1970-01-01
          • 2013-10-03
          • 2015-03-03
          • 1970-01-01
          • 2021-03-21
          相关资源
          最近更新 更多