读取CAN .asc文件并绘制指定数据时无预期输出的问题求助
问题分析与解决方案
核心问题梳理
- 循环逻辑完全失效:后续转换数据的
for item in data循环根本不会执行,因为data初始是空列表。同时电压/电流的提取判断缩进错误,不在行数据拆分的有效块内,无法正确捕获每一行的目标数据。 - 时间数据未收集:
timestamps列表始终为空,绘图时没有有效的X轴数据。 - 数据提取位置错误:从提供的文件片段看,你对
1E3和4E3帧的十六进制数据位置判断错误,取到的不是目标电压/电流对应的字节。 - 多余的文件操作:
with open语句会自动关闭文件,后续的file.close()属于无效操作,还可能引发报错。
修正后的代码
import pandas as pd import matplotlib.pyplot as plt file_path = 'StartupElektroMode.asc' timestamps = [] voltage_data = [] current_data = [] try: with open(file_path, 'r') as file: lines = file.readlines() except FileNotFoundError: print(f"Error: The file '{file_path}' was not found") exit() # 遍历有效行(跳过前6行表头) for line in lines[6:]: parts = line.split() if len(parts) < 6: continue # 跳过格式不完整的行 timestamp = float(parts[0]) can_id = parts[2] # 处理1E3帧:提取前两个数据字节计算电压(需根据实际协议确认字节位置) if can_id == '1E3' and len(parts) >= 14: # 确保包含8个数据字节 hex1, hex2 = parts[6], parts[7] voltage = (int(hex1, 16) * 256 + int(hex2, 16)) * 0.25 timestamps.append(timestamp) voltage_data.append(voltage) # 处理4E3帧:提取对应数据字节计算电流(需根据实际协议确认字节位置) elif can_id == '4E3' and len(parts) >= 14: hex1, hex2 = parts[6], parts[7] current = (int(hex1, 16) * 256 + int(hex2, 16)) * 0.25 timestamps.append(timestamp) current_data.append(current) # 处理数据长度不一致的情况,填充缺失值为NaN max_len = max(len(timestamps), len(voltage_data), len(current_data)) timestamps += [None] * (max_len - len(timestamps)) voltage_data += [None] * (max_len - len(voltage_data)) current_data += [None] * (max_len - len(current_data)) # 创建DataFrame并清理无效数据 data = {'Time': timestamps, 'Voltage': voltage_data, 'Current': current_data} df = pd.DataFrame(data).dropna(subset=['Time']) # 绘制子图展示数据 fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10)) # 电压曲线 ax1.plot(df['Time'], df['Voltage'], label='Voltage (1E3)', color='blue') ax1.set_title('Voltage Over Time') ax1.set_xlabel('Time (s)') ax1.set_ylabel('Voltage (V)') ax1.legend() ax1.grid(True) # 电流曲线 ax2.plot(df['Time'], df['Current'], label='Current (4E3)', color='red') ax2.set_title('Current Over Time') ax2.set_xlabel('Time (s)') ax2.set_ylabel('Current (A)') ax2.legend() ax2.grid(True) plt.tight_layout() plt.show()
额外说明
- 数据字节的提取位置需要根据实际CAN协议确认,如果你知道
1E3和4E3帧中电压/电流对应的具体字节偏移,调整parts[X]的索引即可。 - 如果电压和电流帧不是同步出现的,建议用字典按时间戳存储数据,再统一构建DataFrame,避免数据错位。
内容的提问来源于stack exchange,提问作者T3chWarri0r
相关产品推荐
相关产品推荐

