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

树莓派项目Matplotlib动态绘图更新异常问题求助

解决树莓派Matplotlib实时动态绘图问题

嘿,我一看你的代码就知道问题出在哪了——你每次循环都调用plt.show(),这玩意儿会阻塞程序,非得等你关掉窗口才会继续跑下一次循环,而且每次plt.plot()都会在图上叠加新的线条,根本不是实时更新的效果。咱们改改就能实现终端打数据、窗口实时更图的需求,看下面的方案:

关键修改点

  • 开启Matplotlib的交互式模式(plt.ion()),让绘图窗口保持打开且不阻塞程序运行
  • 提前初始化画布、坐标轴和需要绘制的线条,循环里只更新数据而不是重新绘图
  • 用canvas.draw()/canvas.flush_events()来刷新画面,替代重复调用plt.show()

修改后的完整代码

import matplotlib.pyplot as plt
from time import sleep
from Adafruit_CCS811 import Adafruit_CCS811

# 初始化传感器
ccs = Adafruit_CCS811()
while not ccs.available():
    pass
temp = (ccs.calculateTemperature() / 3.2) - 32.0
ccs.tempOffset = temp - 25.0

# 开启Matplotlib交互式模式
plt.ion()
# 创建画布和坐标轴
fig, ax = plt.subplots(figsize=(8, 5))
# 初始化三条数据线条,先给空数据,后续更新
co2_line, = ax.plot([], [], label='CO2 (ppm)')
tvoc_line, = ax.plot([], [], label='TVOC')
temp_line, = ax.plot([], [], label='Temperature (°C)')

# 设置绘图样式
ax.set_title('Real-time Sensor Data')
ax.set_xlabel('Time (s)')
ax.set_ylabel('Value')
ax.legend()
ax.grid(True)

# 初始化时间序列和数据存储列表
time_points = []
co2_data = []
tvoc_data = []
temp_data = []
current_time = 0

try:
    while True:
        if ccs.available():
            temp = ccs.calculateTemperature()
            if not ccs.readData():
                # 获取当前传感器数据
                co2 = ccs.geteCO2()
                tvoc = ccs.getTVOC()
                # 打印到终端
                print(f"CO2: {co2} ppm, TVOC: {tvoc}, temp: {temp:.1f}")
                
                # 更新数据列表
                time_points.append(current_time)
                co2_data.append(co2)
                tvoc_data.append(tvoc)
                temp_data.append(temp)
                
                # 更新三条线条的数据
                co2_line.set_data(time_points, co2_data)
                tvoc_line.set_data(time_points, tvoc_data)
                temp_line.set_data(time_points, temp_data)
                
                # 自动调整坐标轴范围,避免数据超出视野
                ax.relim()
                ax.autoscale_view()
                
                # 刷新画布
                fig.canvas.draw()
                fig.canvas.flush_events()
                
                # 时间递增(每2秒一次循环,所以加2)
                current_time += 2
            else:
                print("ERROR!")
                break
        sleep(2)
except KeyboardInterrupt:
    # 捕获Ctrl+C,关闭绘图窗口
    plt.close('all')
    print("程序已终止")

代码解释

  1. 交互式模式:plt.ion()让Matplotlib进入交互模式,窗口打开后不会阻塞后续代码执行,这是实时绘图的核心。
  2. 复用线条对象:一开始就创建co2_line、tvoc_line这些线条对象,循环里只调用set_data()更新它们的数据源,而不是每次都用plt.plot()画新线,这样不会产生线条叠加的问题。
  3. 画布刷新:fig.canvas.draw()重绘画布,fig.canvas.flush_events()处理窗口的事件(比如鼠标操作),确保画面实时更新。
  4. 异常处理:加上KeyboardInterrupt捕获,方便你用Ctrl+C终止程序时能正常关闭绘图窗口。

这样改完之后,你运行代码就能看到一个持续更新的绘图窗口,同时终端也会实时打印传感器数据,不用再关窗口才能更新啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:30:20