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

树莓派运行Matplotlib实时数据动画出现内存溢出如何解决

内存不足问题根因
  • 全局xs列表持续泄漏:你在animate函数内执行xs = ['T-9'...'Now']属于局部变量重新赋值,并没有修改外部全局的xs列表,外部列表每次调用append(i)后没有做截断,会无限变长,占用内存持续升高。
  • 重复创建绘图对象:每次执行ax.clear()后重新调用plot()生成新的线条对象,旧的线条对象没有被及时回收,长期运行会累积大量无效绘图对象。
  • 不必要的内存操作:频繁调用gc.collect()本身也会占用额外资源,优化对象复用后无需手动触发垃圾回收。
核心疑问解答
  1. 能不能关闭绘图窗口还保留实时数据展示功能?

实时可视化展示必须依赖绘图窗口渲染,如果不需要可视化只需要后台接收存储数据,可以直接删除所有matplotlib相关逻辑,只保留串口读取和数据落盘的代码即可,内存占用会大幅降低。如果需要保留可视化能力,就不能关闭绘图窗口,但可以通过优化渲染逻辑把内存占用稳定在极低水平。

  1. 能不能每次执行animate函数时新建并关闭一个新的figure?

完全不建议这么做,新建、销毁figure的开销远高于复用同一个figure,反而会大幅提升内存占用和CPU消耗,加剧卡顿和内存不足问题,正确做法是复用同一个figure和绘图对象,仅更新数据内容。

优化后可稳定运行的代码
import serial
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# 初始化绘图对象,仅创建一次
fig, axRT1 = plt.subplots()
# 固定x轴标签,不需要动态append
xs = ['T-9','T-8','T-7','T-6','T-5','T-4','T-3','T-2','T-1','Now']
# 初始化线条对象,后续仅更新y轴数据
lineAC, = axRT1.plot(xs, [0]*10, 'b:', label='Mains', linewidth = 4)
lineDC, = axRT1.plot(xs, [0]*10, 'g--', label='Solar', linewidth = 4)
axRT1.legend()
# 固定y轴范围避免每次重算,可根据实际数据范围调整
axRT1.set_ylim(0, 100)

ysAC = []
ysDC = []

ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
ser.flush()

def getValues():
  if ser.in_waiting > 0:
    line = ser.readline().decode('utf-8').rstrip()   
    return list(map(float, line.split(",")))  # 提前转成数值类型
  return None

def animate(i):
  values = getValues()
  if not values:
    return lineAC, lineDC
  
  wAC = values[1]
  wDC = values[2]
 
  # 仅维护最近10条数据
  ysAC.append(wAC)
  ysDC.append(wDC)
  ysAC[:] = ysAC[-10:]
  ysDC[:] = ysDC[-10:]

  # 数据不足10条时直接返回,够了再更新线条数据
  if len(ysDC) == 10:
    lineAC.set_ydata(ysAC)
    lineDC.set_ydata(ysDC)
    
  # 开启blit后只返回需要更新的对象,渲染效率提升数倍
  return lineAC, lineDC

# 开启blit,去掉不需要的参数
ani = animation.FuncAnimation(fig, animate, interval=1000, blit=True)
plt.get_current_fig_manager().full_screen_toggle()
plt.show()
额外优化建议
  • 可以根据你的实际串口数据范围调整axRT1.set_ylim()的上下限,避免动态计算轴范围的额外开销。
  • 如果不需要全屏展示可以去掉全屏相关代码,进一步降低渲染开销。
  • 树莓派如果性能较低,可以把interval调大到2000(2秒刷新一次),进一步降低资源占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:27:04