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

如何在Notebook中实现Matplotlib单图随时间步动态更新,不新增窗口

Notebook 环境 Matplotlib 单画布实时更新解决方案

前置配置

原有示例失效的核心原因是:这些示例是为本地Python GUI运行环境设计的,Jupyter Notebook默认的静态渲染后端不支持实时画布更新,会每次渲染生成新图片。首先在代码开头运行魔法命令配置交互后端:

# 配置Matplotlib交互后端,支持画布内更新
%matplotlib ipympl
# 如果上面的命令报错,可以换成%matplotlib notebook,是旧版交互后端

如果提示没有安装ipympl,先执行终端命令pip install ipympl安装即可。

方案1:使用官方FuncAnimation接口(最稳定,推荐)

这是Matplotlib官方推荐的动画实现方式,性能更高,不会出现重复弹出窗口/生成新图的问题,示例代码如下:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
from collections import deque
import numpy as np

# 初始化数据容器
max_len = 100
a1 = deque([0]*max_len)

# 初始化画布和绘图对象,只创建一次
fig, ax = plt.subplots()
ax.set_ylim(0, 10)
ax.set_xlim(0, max_len)
line, = ax.plot(a1)

# 模拟数据生成
def random_gen():
    return random.randint(1,10)

# 每帧更新函数,FuncAnimation会自动调用
def update(frame):
    a1.appendleft(random_gen())
    a1.pop()
    line.set_ydata(a1)
    # 返回需要更新的绘图对象,提高渲染性能
    return line,

# 启动动画:interval是每帧间隔(毫秒),blit开启增量渲染
ani = FuncAnimation(fig, update, interval=100, blit=True, save_count=20)
plt.show()

如果需要停止动画,调用ani.event_source.stop()即可。

方案2:手动循环更新(适配原有代码逻辑)

如果需要保留原来的循环业务逻辑,可以配合IPython的显示控制实现单画布更新,示例代码如下:

import matplotlib.pyplot as plt
import time
import random
from collections import deque
from IPython.display import clear_output, display

# 初始化数据
a1 = deque([0]*100)
d = (random.randint(1,10) for _ in iter(int, 1)) # 模拟生成器

# 只初始化一次画布
fig, ax = plt.subplots(figsize=(8,4))
ax.set_ylim(0, 10)
ax.set_xlim(0, 20)
line, = ax.plot(a1)

# 循环更新
for i in range(20):
    a1.appendleft(next(d))
    a1.pop()
    line.set_ydata(a1)
    # 清除旧输出,重绘画布
    clear_output(wait=True)
    display(fig)
    print(f"当前最新值:{a1[0]}")
    time.sleep(0.1)

# 循环结束后关闭额外的空白画布
plt.close()

备选方案:使用Plotly实现更流畅的动态图

如果不需要绑定Matplotlib,Plotly的交互图在Notebook里体验更好,不需要额外配置后端,示例代码:

import plotly.graph_objects as go
import random
import time
from collections import deque

max_len = 100
a1 = deque([0]*max_len)
fig = go.FigureWidget()
fig.add_scatter(y=list(a1))
fig.update_layout(yaxis_range=[0,10], xaxis_range=[0, max_len])
display(fig)

for i in range(20):
    a1.appendleft(random.randint(1,10))
    a1.pop()
    # 直接更新数据,无需重绘整个图
    fig.data[0].y = list(a1)
    time.sleep(0.1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:54:04