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

如何在while循环每次迭代时实时更新同一matplotlib绘图

解决方案

你遇到的每次循环新建绘图窗口的问题,核心是没有提前初始化固定画布、未开启matplotlib交互模式,且没有在每帧更新时复用同一个绘图对象。

基础实现(逻辑简单易调试)

先把画布初始化逻辑移到循环外部,开启交互模式,每帧清空上一帧内容后重绘即可,代码修改如下:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# ========== 以下初始化代码放在while循环外部,不要放进循环里 ==========
plt.ion()  # 开启matplotlib交互模式,绘图不会阻塞后续代码执行
fig, ax = plt.subplots(figsize=(6, 6))  # 创建固定的画布与坐标轴对象,全程复用
# ==================================================================

while cap.isOpened():
    # 保留你原有的视频读取、mediapipe姿态检测逻辑
    pose = results.pose_landmarks.landmark
    pose_row_x = list(np.array([[landmark.x] for landmark in pose]).flatten())
    pose_row_y = list(np.array([[landmark.y] for landmark in pose]).flatten())
    pose_row_z = list(np.array([[landmark.z] for landmark in pose]).flatten())

    df = pd.DataFrame(data=[pose_row_x, pose_row_y, pose_row_z ]).T
    df.columns = ["x", "y", "z"]

    # ========== 每帧更新绘图 ==========
    ax.cla()  # 清空坐标轴上上一帧的绘制内容
    # 固定坐标范围,避免每帧自动缩放导致画面抖动,反转y轴匹配图像坐标系
    ax.set_xlim(0, 1)
    ax.set_ylim(1, 0)
    ax.scatter(df['x'], df['y'], c='red', s=15)  # 绘制当前帧的姿态点
    plt.draw()  # 触发画布重绘
    plt.pause(0.001)  # 预留GUI刷新时间,设为0会导致窗口卡死无响应

高性能实现(流畅度更高,适合高帧率场景)

如果需要更高的刷新帧率,可以不用每帧清空重建散点对象,直接更新已有散点的坐标数据,减少重绘开销:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# ========== 循环外初始化 ==========
plt.ion()
fig, ax = plt.subplots(figsize=(6, 6))
ax.set_xlim(0, 1)
ax.set_ylim(1, 0)
# 提前创建空散点对象
scatter = ax.scatter([], [], c='red', s=15)
# =================================

while cap.isOpened():
    # 保留原有视频读取、姿态检测、DataFrame构建逻辑
    pose = results.pose_landmarks.landmark
    pose_row_x = list(np.array([[landmark.x] for landmark in pose]).flatten())
    pose_row_y = list(np.array([[landmark.y] for landmark in pose]).flatten())
    pose_row_z = list(np.array([[landmark.z] for landmark in pose]).flatten())

    df = pd.DataFrame(data=[pose_row_x, pose_row_y, pose_row_z ]).T
    df.columns = ["x", "y", "z"]

    # ========== 直接更新散点坐标,无需清空重绘 ==========
    scatter.set_offsets(df[['x', 'y']].values)
    plt.draw()
    plt.pause(0.001)

关键注意事项

  • 不要把画布、轴对象的初始化代码放进循环,放到循环内就会每次迭代新建窗口,就是你当前遇到的问题
  • plt.pause()不能省略,否则matplotlib的GUI事件没有处理时间,会出现窗口未响应、画面不刷新的问题
  • 必须固定坐标轴范围,否则每帧绘图会自动适配数据范围调整缩放,导致画面跳变
  • 反转y轴是为了匹配mediapipe输出的图像坐标系(原点在左上角),和你预期的姿态显示方向一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:24:31