Python树莓派传感器实时绘图报KeyError: 'x_value'错误求助
问题根因
- 数据采集脚本仅在控制台打印了列名,没有将
x_value等表头写入data.csv文件,pandas读取csv时默认将第一行传感器数据识别为表头,自然找不到x_value列。
- 数据采集脚本仅在控制台打印了列名,没有将
- 写入csv时使用了
{:>4}这类右对齐格式,数值前带多余空格,即使后续加了表头也可能因为列名/数值存在多余空格导致匹配失败。
- 写入csv时使用了
- 其他潜在问题:采集脚本缩进错误、频繁开关文件可能丢数据、绘图脚本刷新间隔设置不合理、运行顺序不对也可能触发该报错。
修复方案
第一步:修改数据采集脚本
from datetime import datetime import time import busio import digitalio import board import adafruit_mcp3xxx.mcp3008 as MCP from adafruit_mcp3xxx.analog_in import AnalogIn import RPi.GPIO as GPIO import os # 新增,用于判断文件状态 fieldnames = ["x_value", "D_1", "D_2", "D_3", "D_4", "D_5", "D_6"] csv_path = 'data.csv' # 新增:文件为空/不存在时先写入表头 if not os.path.exists(csv_path) or os.path.getsize(csv_path) == 0: with open(csv_path, 'w', encoding='utf-8') as f: f.write(','.join(fieldnames) + '\n') spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI) cs = digitalio.DigitalInOut(board.D5) mcp = MCP.MCP3008(spi, cs) print('x_value, D_1, D_2, D_3, D_4, D_5, D_6') print('-' * 67) while True: try: values = [0]*8 for i in range(8): values[i] = mcp.read(i) d=datetime.now() for i in range(6): values[i] = round(((-25.74257)*(values[i]*0.00488758553))+65) # 控制台打印保留对齐格式不影响 print('{:%M.%S}, {:>4}, {:>4}, {:>4}, {:>4}, {:>4}, {:>4}'.format(d, values[0], values[1],values[2], values[3], values[4], values[5])) # 写入csv时去掉多余空格,仅用逗号分隔 str1 = f"{d:%M.%S},{values[0]},{values[1]},{values[2]},{values[3]},{values[4]},{values[5]}\n" # 改用with上下文管理,自动关闭文件 with open(csv_path, 'a', encoding='utf-8') as fout: fout.write(str1) except RuntimeError as error: print('failed') time.sleep(1.0) # 修正缩进,放在while循环内部
第二步:修改绘图脚本
import csv from itertools import count import pandas as pd import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation plt.style.use('fivethirtyeight') x_vals = [] y_vals = [] index = count() def animate(i): try: # 新增异常捕获,避免csv被写入时读取失败报错 data = pd.read_csv('data.csv', header=0) # 明确指定第一行为表头 x = data['x_value'] y1 = data['D_1'] y2 = data['D_2'] y3 = data['D_3'] y4 = data['D_4'] y5 = data['D_5'] y6 = data['D_6'] plt.cla() plt.plot(x, y1, label='Sensor 1') plt.plot(x, y2, label='Sensor 2') plt.plot(x, y3, label='Sensor 3') plt.plot(x, y4, label='Sensor 4') plt.plot(x, y5, label='Sensor 5') plt.plot(x, y6, label='Sensor 6') plt.legend(loc='upper left') plt.tight_layout() except Exception as e: pass # 跳过异常帧,等待下次刷新 # interval单位为毫秒,改为1000和采集频率对齐,原1ms会导致性能浪费 ani = FuncAnimation(plt.gcf(), animate, interval=1000) plt.tight_layout() plt.show()
运行注意事项
- 必须先运行数据采集脚本,等1~2秒确认
data.csv已经生成并写入数据后,再运行绘图脚本 - 如果之前已经生成了错误的
data.csv,请先删除旧文件,再运行修改后的代码
内容的提问来源于stack exchange,提问作者Milon
相关产品推荐
相关产品推荐

