如何从Arduino温度文本生成精简Python列表用于温度曲线绘制?
问题
我正在研究城市与森林的温度差异,用6个Arduino温度传感器采集了12小时的每秒一条温度数据。已经写了两个Python程序:一个负责把Arduino的数据写入文本文件,另一个把文本文件转换成对应每个传感器的Python列表。但每个列表大概有23337个值,数据量太大,想在转换的时候跳过部分值来精简列表,用于绘制温度随时间变化的曲线,不知道该怎么实现。
文本文件格式示例
Sensor 1 : 14.56 Sensor 2 : 14.13 Sensor 3 : 14.19 Sensor 4 : 14.13 Sensor 5 : 12.56 Sensor 6 : 14.31 Sensor 1 : 14.63 Sensor 2 : 14.19 Sensor 3 : 14.19 Sensor 4 : 14.13 Sensor 5 : 12.56 Sensor 6 : 14.31 Sensor 1 : 14.63 Sensor 2 : 14.19 Sensor 3 : 14.19 Sensor 4 : 14.19 Sensor 5 : 12.63 Sensor 6 : 14.31 Sensor 1 : 14.56 Sensor 2 : 14.19 Sensor 3 : 14.19 Sensor 4 : 14.13 Sensor 5 : 12.56 Sensor 6 : 14.31 Sensor 1 : 14.63 Sensor 2 : 14.13 Sensor 3 : 14.13 Sensor 4 : 14.13 Sensor 5 : 12.56 Sensor 6 : 14.31
现有Python代码
import matplotlib.pyplot as plt import numpy as np import serial import os X=[] for i in range(23337): X.append(float(i)) with open("temperaturevilleforet120523.txt","r") as f: A=[] B=[] C=[] D=[] E=[] F=[] for i in range(23337): L=f.readline().split(' ') print(L) A.append(float(L[3])) B.append(float(L[7])) C.append(float(L[11])) D.append(float(L[15])) E.append(float(L[19])) F.append(float(L[23])) f.readline() f.readline() #want to skip about 300 lines of values plt.title("évolution de la température en fonction du temps") plt.xlabel("Temps (s)") plt.ylabel("Température (°C)") plt.plot(X,A,label="Capteur ville 3 (°C)") plt.plot(X,B,label="Capteur forêt 1 (°C)") plt.plot(X,C,label="Capteur forêt 3 (°C)") plt.plot(X,D,label="Capteur forêt 2 (°C)") plt.plot(X,E,label="Capteur ville 2 (°C)") plt.plot(X,F,label="Capteur ville 1 (°C)") plt.legend() plt.show()
解决方案
方法1:固定间隔采样(每N条取1条)
比如你想每300条数据保留1条,可通过判断循环索引实现,同时同步生成对应时间戳,避免数据长度不匹配问题。修改后的代码如下:
import matplotlib.pyplot as plt import numpy as np # 设置采样间隔:每300条数据取1条 sample_interval = 300 X = [] A = [] B = [] C = [] D = [] E = [] F = [] with open("temperaturevilleforet120523.txt","r") as f: data_index = 0 while True: # 读取数据行,文件读完则退出循环 data_line = f.readline() if not data_line: break data_index += 1 # 只保留符合间隔条件的数据 if data_index % sample_interval == 1: # 拆分字符串并过滤空元素,避免多余空格导致索引错误 L = [item for item in data_line.strip().split(' ') if item] A.append(float(L[3])) B.append(float(L[7])) C.append(float(L[11])) D.append(float(L[15])) E.append(float(L[19])) F.append(float(L[23])) # 同步生成对应时间(每秒一条,时间为(data_index-1)秒) X.append(float(data_index - 1)) # 跳过数据行后的两个空行 f.readline() f.readline() plt.title("温度随时间变化曲线") plt.xlabel("时间 (秒)") plt.ylabel("温度 (°C)") plt.plot(X,A,label="城市传感器3 (°C)") plt.plot(X,B,label="森林传感器1 (°C)") plt.plot(X,C,label="森林传感器3 (°C)") plt.plot(X,D,label="森林传感器2 (°C)") plt.plot(X,E,label="城市传感器2 (°C)") plt.plot(X,F,label="城市传感器1 (°C)") plt.legend() plt.show()
方法2:按时间间隔采样(如每5分钟取1条)
因为数据是每秒一条,5分钟等于300秒,直接把sample_interval设为300即可,这样得到的点对应每5分钟一个数据,既精简了数据量,又能完整保留温度变化趋势。
额外优化说明
- 替换原固定行数循环为
while True读取到文件结尾,避免文件行数变化导致的错误 - 拆分字符串后过滤空元素,解决多余空格或换行带来的索引异常
- 同步生成时间戳,确保时间轴与温度数据长度完全匹配
内容的提问来源于stack exchange,提问作者Mienko
相关产品推荐
相关产品推荐

