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

Pyplot子图无法随时间实时更新的问题排查

实时折线图问题排查与修复

问题现象

开发长期数据记录+实时折线图项目时,其他功能正常,但实时折线图存在两个核心问题:

  1. 子图轴范围被完全重置(偏离初始设置的x轴0-30、y轴0-100)
  2. 绘制的线条“不可见”

用户提供的相关代码

导入模块

import matplotlib 
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import pyplot as plt
from matplotlib import style
from tkinter import *
from PIL import Image
import numpy as np
import serial
from serial import Serial
import sqlite3
import time
from datetime import datetime
from array import *
import cv2
from pathlib import Path
from itertools import count

数据存储数组

A=[0,0,0,0,0,0,0,0]

数组每个索引对应一个传感器的最新读数(i=0对应传感器1)。

子图定义

fig1 = plt.Figure(dpi=100, facecolor="#f0f0f0")
a = fig1.add_subplot(111)
a.patch.set_facecolor("#f0f0f0")

a.set_xlabel('time (Sec)')
a.set_ylabel('pressure(kPa)')
a.set_ylim(0,100)
a.set_xlim(0,30)

graph1 = FigureCanvasTkAgg(fig1, master=root)
graph1.get_tk_widget().place(x=10, y=220, width=210, height=280)
graph1.draw();

绘图函数

def graph_plotdata():
    global A
    global a
    line1 = []
    time = []
    
    time.append(next(index))
    line1.append(A[0])
    
    a.cla()
    a.plot(time, line1)
        
    graph1.draw()

问题根源与修复方案

1. 轴范围重置问题

  • 原因:a.cla()会清空子图的所有配置(包括轴标签、轴范围、背景色等),直接覆盖了初始设置。
  • 修复:
    避免使用cla()清除整个轴,改为仅更新数据;如果必须清除,在清除后重新恢复轴的配置(标签、范围、背景色)。更高效的方式是预先定义线条对象,后续只更新数据内容。

2. 线条不可见问题

  • 原因:每次调用绘图函数时,line1和time都是重新创建的空列表,仅添加单个数据点,plot默认绘制无标记的单点,自然无法看到折线。
  • 修复:将数据列表定义为全局变量,每次调用函数时追加新数据,而非重新初始化。

完整修复后的代码示例

1. 全局数据初始化

在绘图函数外定义全局存储列表与计数器:

# 全局存储实时数据
time_data = []
pressure_data = []
index = count()  # 假设index已在全局完成初始化

2. 子图初始化(预创建线条对象)

fig1 = plt.Figure(dpi=100, facecolor="#f0f0f0")
a = fig1.add_subplot(111)
a.patch.set_facecolor("#f0f0f0")

a.set_xlabel('time (Sec)')
a.set_ylabel('pressure(kPa)')
a.set_ylim(0,100)
a.set_xlim(0,30)

# 预先创建折线对象,后续仅更新数据
line, = a.plot([], [], 'b-')  # 'b-'指定蓝色折线样式

graph1 = FigureCanvasTkAgg(fig1, master=root)
graph1.get_tk_widget().place(x=10, y=220, width=210, height=280)
graph1.draw();

3. 改进后的绘图函数

def graph_plotdata():
    global A, time_data, pressure_data, line
    
    # 追加新数据
    current_time = next(index)
    current_pressure = A[0]
    
    time_data.append(current_time)
    pressure_data.append(current_pressure)
    
    # 实现x轴滚动:当时间超过30秒时,显示最近30秒的数据
    if current_time > 30:
        a.set_xlim(current_time - 30, current_time)
    
    # 更新折线数据
    line.set_data(time_data, pressure_data)
    
    # 重绘画布
    graph1.draw()

额外优化:使用matplotlib动画模块

如果需要定时自动刷新绘图,建议使用FuncAnimation管理刷新逻辑,性能更稳定:

# 动画更新函数
def update(frame):
    global A, time_data, pressure_data, line
    
    current_time = next(index)
    current_pressure = A[0]
    
    time_data.append(current_time)
    pressure_data.append(current_pressure)
    
    if current_time > 30:
        a.set_xlim(current_time - 30, current_time)
    
    line.set_data(time_data, pressure_data)
    return line,

# 创建动画,每100ms刷新一次(可根据需求调整间隔)
ani = animation.FuncAnimation(fig1, update, interval=100, blit=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:10:47