Python 如何通过每行中的值分隔和绘制数组中的行

Python 如何通过每行中的值分隔和绘制数组中的行,python,datetime,Python,Datetime,我是Python新手,正在尝试从不断增长的CSV中提取数据,并创建实时更新图。我想创建两个不同的x,y阵列,具体取决于数据通过的天线(每行数据中的一个值由逗号分隔)。数据文件如下所示: 时间戳、读取计数、天线、协议、RSSI、EPC、传感器 2016年9月21日15:24:40.560、5499、1、GEN2、-21、E036112D912508B3、23.78、47.00、0.00、2.21,(无限%) 2016年9月21日15:24:41.1385506,1,GEN2,-9,E036112

我是Python新手,正在尝试从不断增长的CSV中提取数据,并创建实时更新图。我想创建两个不同的x,y阵列,具体取决于数据通过的天线(每行数据中的一个值由逗号分隔)。数据文件如下所示:

时间戳、读取计数、天线、协议、RSSI、EPC、传感器
2016年9月21日15:24:40.560、5499、1、GEN2、-21、E036112D912508B3、23.78、47.00、0.00、2.21,(无限%)
2016年9月21日15:24:41.1385506,1,GEN2,-9,E036112D912508B3,23.99,46.00,0.00,2.26,(无限%)
2016年9月21日15:24:41.6235513,1,GEN2,-25E036112D912508B3,23.99,46.00,0.00,2.26,(无限%)
2016年9月21日15:24:42.1205520,1,GEN2,-18E036112D912508B3,23.78,46.00,0.00,2.26,(无限%)
2016年9月21日15:24:42.6335527,1,GEN2,-12,E036112D912508B3,23.99,45.00,0.00,2.23,(无限%)
2016年9月21日15:24:43.211、5534、1、GEN2、-9、E036112D912508B3、23.99、46.00、0.00、2.26,(无限%)

2016年9月21日15:24:43.7445541,1,GEN2,-16,E036112D912508B3,23.99,46.00,0.00,2.26,(无限%)
您可以简单地使用相同的轴绘制每个数据集

下面的方法使用Python
csv.DictReader
帮助读取数据,同时使用
defaultdict(list)
根据每行的天线自动将数据拆分为列表

这还添加了代码,以解决您对分组数据点的评论,这些数据点之间的间隔不超过60秒,并且仅显示最后5分钟的条目:

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation

from datetime import datetime, timedelta
import collections
import csv

offset = -7.4954
slope = 0.9548

def plot(ax, data, colour, width):
    if data:
        last_dt = data[0][0]
        sixty = timedelta(seconds=60)

        x = []
        y = []

        # Plot groups of data not more than 60 seconds apart
        for dt, ten in data:
            if dt <= last_dt + sixty:
                x.append(dt)
                y.append(ten)
            else:
                ax.plot(matplotlib.dates.date2num(x), y, colour, linewidth=width)
                x = [dt]
                y = [ten]

            last_dt = dt

        ax.plot(matplotlib.dates.date2num(x), y, colour, linewidth=width)


def animate(i, fig, ax):
    # Read in the CSV file
    data = collections.defaultdict(list)
    fields = ["TimeStamp", "ReadCount", "Antenna", "Protocol", "RSSI", "EPC", "Temp", "Ten", "Powr", "Unpowr", "Inf"]

    with open('SensorLog.csv') as f_input:
        csv_input = csv.DictReader(f_input, skipinitialspace=True, fieldnames=fields)
        header = next(csv_input)

        # Separate the rows based on the Antenna field
        for row in csv_input:
            try:
                data[row['Antenna']].append(
                    [datetime.strptime(row['TimeStamp'], '%m/%d/%Y %H:%M:%S.%f'), 
                    int(float(row['Ten']) * float(slope) + float(offset))])
            except TypeError as e:
                pass

    # Drop any data points more than 5 mins older than the last entry

    latest_dt = data[row['Antenna']][-1][0]     # Last entry
    not_before = latest_dt - timedelta(minutes=5)

    for antenna, entries in data.items():
        data[antenna] = [[dt, count] for dt, count in entries if dt >= not_before]

    # Redraw existing axis
    ax.clear()

    ax.spines['bottom'].set_color("#5998ff")
    ax.spines['top'].set_color("#5998ff")
    ax.spines['left'].set_color("#5998ff")
    ax.spines['right'].set_color("#5998ff")

    hfmt = matplotlib.dates.DateFormatter('%m/%d/%Y\n%I:%M:%S %p')
    ax.xaxis.set_major_formatter(hfmt)
    fig.autofmt_xdate()

    plot(ax, data['1'], 'c', 2)     # Antenna 1
    plot(ax, data['2'], 'r', 3)     # Antenna 2

    ax.grid(True, color='w')
    plt.ylabel('Tension (lb)', color='w', fontsize=20)
    plt.title('Spiral 1 Tension', color='w', fontsize=26)

    ax.tick_params(axis='y', colors='w')
    ax.tick_params(axis='x', colors='w')

fig = plt.figure(facecolor='#07000d')
ax = fig.add_subplot(111, axisbg='#07000d')

ani = animation.FuncAnimation(fig, animate, fargs=(fig, ax), interval=1000)
plt.show()
导入matplotlib
将matplotlib.pyplot作为plt导入
将matplotlib.animation导入为动画
从datetime导入datetime,timedelta
导入集合
导入csv
偏移量=-7.4954
斜率=0.9548
def绘图(轴、数据、颜色、宽度):
如果数据:
last_dt=数据[0][0]
六十=时间增量(秒=60)
x=[]
y=[]
#绘制间隔不超过60秒的数据组
对于dt,数据中有10个:
如果dt=不在前]
#重新绘制现有轴
ax.clear()
斧头刺['bottom'].设置颜色(“5998ff”)
斧头刺['top'].设置颜色(“5998ff”)
斧头刺[“左”]。设置颜色(“5998ff”)
斧头刺['右'].设置颜色(“5998ff”)
hfmt=matplotlib.dates.DateFormatter(“%m/%d/%Y\n%I:%m:%S%p”)
ax.xaxis.set\u major\u格式化程序(hfmt)
图autofmt_xdate()
绘图(ax,数据['1'],'c',2)#天线1
绘图(ax,数据['2'],'r',3)#天线2
ax.grid(True,color='w')
plt.ylabel('Tension(lb'),color='w',fontsize=20)
plt.title('Spiral 1 Tension',color='w',fontsize=26)
ax.勾选参数(轴为y轴,颜色为w轴)
ax.勾选参数(轴=x',颜色=w')
图=plt.图(面色='#07000d')
ax=图添加_子批次(111,axisbg='#07000d')
ani=animation.FuncAnimation(图,animate,fargs=(图,ax),间隔=1000)
plt.show()
这将为您提供以下类型的输出:


Martin这太棒了-绝对是正确的搭配方式,谢谢!现在我有了另一个问题,我想我可以用Python中的这个csv函数来解决它。“成功”读取的一行数据有11个值(用逗号分隔);但是,如果将传感器从天线上取下,它仍可能从天线上获得杂散读数,而杂散读数不会发回所有11个值,从而导致尝试读取
10个
时出错。我可以在哪里放置IF语句来过滤没有11个值的csv行?还有一种方法可以防止matplotlib在距离最后一个数据点至少60秒后自动将来自同一天线的两个数据点与一条线连接起来?我得到了这条恼人的插值线性线,如果传感器超出读取距离,2分钟后返回,它将出现-这表明张力增加,但这并没有发生,我宁愿让这个数据间隙为空。有什么想法吗?我已经更新了脚本以跳过缺少的
10个
字段条目。要断开相隔60秒以上的数据连接,您需要对数据进行分组,并对每组进行绘图。我意识到,有时最后一列的“(无穷%)会被读取为十个值-不用说,我会在
数据[row['Antenna']之前输入
try:
和一个
除了:pass
之后,我认为有效地跳过没有所有数据值的行?如果是这样,那就完美了!嗯…对数据进行分组并对每组进行绘图。我有点不知道该怎么做。在这方面还有什么帮助吗?考虑到你的数据,那会更好。