You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jupyter Notebook函数内HTML(anim.to_jshtml())无法显示动画的问题

Jupyter Notebook中Matplotlib动画封装到函数后不显示的解决办法

这绝对是Jupyter玩Matplotlib动画时的经典坑!我来给你唠明白为啥会这样,还有两种直接在函数里显示动画的办法~

先明确问题现象

  • 直接在单元格里写代码运行,HTML(anim.to_jshtml())能正常弹出交互动画控件
  • 把代码塞进函数里调用,就只显示一张静态图,动画完全出不来
  • 但如果从函数返回anim对象,再手动调用HTML(anim.to_jshtml()),又能正常显示

不工作的函数封装代码示例

from matplotlib import animation, rc
from IPython.display import HTML
import numpy as np
import matplotlib.pyplot as plt

def plot_anim_funct():
    fig, ax = plt.subplots()
    ax.set_xlim((0, 2))
    ax.set_ylim((-2, 2))
    line, = ax.plot([], [], lw=2)

    def init():
        line.set_data([], [])
        return (line,)

    def animate(i):
        x = np.linspace(0, 2, 1000)
        y = np.sin(2 * np.pi * (x - 0.01 * i))
        line.set_data(x, y)
        return (line,)

    anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=20, blit=True)
    HTML(anim.to_jshtml())  # 这里创建了HTML对象,但没让Jupyter渲染它

plot_anim_funct()

为啥会这样?

核心原因就是Jupyter的单元格输出逻辑:

  • 当你在单元格里直接写HTML(xxx),它是单元格的最后一个表达式,Jupyter会自动把这个对象的渲染结果输出
  • 但在函数内部调用HTML(xxx)时,这个对象只是在函数内部生成了,没有被返回或者主动输出,Jupyter根本不知道要渲染它
  • 你看到的静态图,是animation.FuncAnimation创建时Matplotlib自动生成的默认静态绘图,和动画控件没关系

解决办法:两种方式在函数内显示动画

办法1:主动返回HTML对象,让Jupyter渲染

这是你已经发现的方式,把HTML(anim.to_jshtml())作为函数返回值,调用函数时Jupyter就会自动渲染它:

from matplotlib import animation, rc
from IPython.display import HTML
import numpy as np
import matplotlib.pyplot as plt

def plot_anim_funct():
    fig, ax = plt.subplots()
    ax.set_xlim((0, 2))
    ax.set_ylim((-2, 2))
    line, = ax.plot([], [], lw=2)

    def init():
        line.set_data([], [])
        return (line,)

    def animate(i):
        x = np.linspace(0, 2, 1000)
        y = np.sin(2 * np.pi * (x - 0.01 * i))
        line.set_data(x, y)
        return (line,)

    anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=20, blit=True)
    # 返回HTML对象,让Jupyter渲染
    return HTML(anim.to_jshtml())

# 调用函数,自动显示动画
plot_anim_funct()

办法2:在函数内部主动输出HTML对象

用IPython.display里的display()函数,直接在函数里把HTML动画控件输出,不用返回也能显示:

from matplotlib import animation, rc
from IPython.display import HTML, display
import numpy as np
import matplotlib.pyplot as plt

def plot_anim_funct():
    fig, ax = plt.subplots()
    ax.set_xlim((0, 2))
    ax.set_ylim((-2, 2))
    line, = ax.plot([], [], lw=2)

    def init():
        line.set_data([], [])
        return (line,)

    def animate(i):
        x = np.linspace(0, 2, 1000)
        y = np.sin(2 * np.pi * (x - 0.01 * i))
        line.set_data(x, y)
        return (line,)

    anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=20, blit=True)
    # 主动调用display输出动画控件
    display(HTML(anim.to_jshtml()))

# 直接调用函数就会弹出动画
plot_anim_funct()

额外小技巧:去掉多余的静态图

如果不想看到那个碍眼的静态图,可以在函数里加上plt.close(fig),把FuncAnimation生成的默认静态图关掉:

def plot_anim_funct():
    fig, ax = plt.subplots()
    ax.set_xlim((0, 2))
    ax.set_ylim((-2, 2))
    line, = ax.plot([], [], lw=2)

    def init():
        line.set_data([], [])
        return (line,)

    def animate(i):
        x = np.linspace(0, 2, 1000)
        y = np.sin(2 * np.pi * (x - 0.01 * i))
        line.set_data(x, y)
        return (line,)

    anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=20, blit=True)
    # 关闭当前figure,避免静态图输出
    plt.close(fig)
    display(HTML(anim.to_jshtml()))

内容的提问来源于stack exchange,提问作者Marses

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:38:24