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

使用matplotlib.animation从CSV实时绘图:数据连接至首个条目错误

问题原因分析

你遇到的额外线条问题,核心原因在于全局变量x、y1、y2、y3在每次动画更新时没有被清空,且每次都会重新读取整个CSV文件的所有数据并追加到列表中。

举个实际场景的例子:

  • 第一次调用animate函数时,读取了CSV里的现有数据,列表里存储了第1条数据;
  • 第二次调用(1秒后,CSV新增了第2条数据),你的代码会再次读取整个CSV的所有数据(第1+第2条),并把这两条数据追加到已经存着第1条数据的列表里。此时x变成[time1, time1, time2],y1变成[v1, v1, v2];
  • 当ax1.plot(x,y1)执行时,会按顺序连接所有点:time1→v1 → time1→v1 → time2→v2。下一次动画更新时,列表又会追加第1+第2+第3条数据,最终导致绘图时出现从最新数据点跳回首个数据点的多余线条——因为列表里重复的旧数据会被重复绘制。
修复方案

有两种简单的修复方式,推荐第一种(更清晰,避免全局变量的副作用):

方案1:在animate函数内部初始化列表

把x、y1等列表的定义放到animate函数内部,这样每次调用函数都会创建全新的空列表,读取最新的CSV数据填充,不会有旧数据残留:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import datetime as dt
import csv

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

def animate(i):
    # 每次动画更新都创建新的空列表
    x = [] 
    y1 = []
    y2 = []
    y3 = []
    with open( 'data_log.csv', 'r') as csvfile:
        alphasensefile = csv.reader(csvfile, delimiter = ',')
        # 跳过前三行说明/表头
        next(alphasensefile, None)
        next(alphasensefile, None)
        next(alphasensefile, None)
        for column in alphasensefile:
            a = dt.datetime.strptime((column[0]), '%H:%M:%S')
            x.append(a)
            # 注意:CSV读取的是字符串,转成数值类型避免绘图异常
            y1.append(float(column[1]))
            y2.append(float(column[2]))
            y3.append(float(column[3]))
    ax1.clear()
    ax1.plot(x,y1)

ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()

方案2:清空全局列表后再读取数据

如果你需要保留全局变量的结构,可以在每次读取CSV前清空列表:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import datetime as dt
import csv

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
x=[] ; y1=[]; y2=[]; y3=[]

def animate(i):
    # 清空全局列表,避免旧数据残留
    x.clear()
    y1.clear()
    y2.clear()
    y3.clear()
    with open( 'data_log.csv', 'r') as csvfile:
        alphasensefile = csv.reader(csvfile, delimiter = ',')
        next(alphasensefile, None)
        next(alphasensefile, None)
        next(alphasensefile, None)
        for column in alphasensefile:
            a = dt.datetime.strptime((column[0]), '%H:%M:%S')
            x.append(a)
            y1.append(float(column[1]))
            y2.append(float(column[2]))
            y3.append(float(column[3]))
    ax1.clear()
    ax1.plot(x,y1)

ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()
额外优化提示
  • 代码里加了float()转换:CSV读取的所有数据都是字符串类型,直接用于绘图可能会有异常,转成数值类型更稳妥;
  • 如果CSV文件后期变大,每次读取整个文件会影响性能,可以考虑记录上次读取的行数,下次只读取新增的行(不过对于传感器实时日志,一般数据量不大,当前方案足够用)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:46:22