2016-09-21 11 views
1

私はPythonが新しく、成長するCSVからデータを引き出し、ライブ更新プロットを作成しようとしています。私は、データが通過するアンテナ(データの各行の値の1つをコンマで区切って)に応じて、2つの異なるx、y配列を作成したいと考えています。データファイルには、次のようになります私は成功したグラフを示しているが、ただ一つのxへのデータのすべての行にとる必要があり各行の値で配列の行を区切ってグラフ化する方法

TimeStamp, ReadCount, Antenna, Protocol, RSSI, EPC, Sensor 
 
09/21/2016 15:24:40.560, 5499, 1, GEN2, -21, E036112D912508B3, 23.78,47.00,0.00,2.21, (Infinity%) 
 
09/21/2016 15:24:41.138, 5506, 1, GEN2, -9, E036112D912508B3, 23.99,46.00,0.00,2.26, (Infinity%) 
 
09/21/2016 15:24:41.623, 5513, 1, GEN2, -25, E036112D912508B3, 23.99,46.00,0.00,2.26, (Infinity%) 
 
09/21/2016 15:24:42.120, 5520, 1, GEN2, -18, E036112D912508B3, 23.78,46.00,0.00,2.26, (Infinity%) 
 
09/21/2016 15:24:42.633, 5527, 1, GEN2, -12, E036112D912508B3, 23.99,45.00,0.00,2.23, (Infinity%) 
 
09/21/2016 15:24:43.211, 5534, 1, GEN2, -9, E036112D912508B3, 23.99,46.00,0.00,2.26, (Infinity%) 
 
09/21/2016 15:24:43.744, 5541, 1, GEN2, -16, E036112D912508B3, 23.99,46.00,0.00,2.26, (Infinity%)

コードは、配列のYセットは、次のようになります。 :私はSEにしようとしています

import matplotlib 
 
import matplotlib.pyplot as plt 
 
import matplotlib.animation as animation 
 
from datetime import datetime 
 
     
 
offset = -7.4954 
 
slope = 0.9548 
 

 
fig = plt.figure(facecolor='#07000d') 
 

 
ax1 = fig.add_subplot(111, axisbg='#07000d') 
 

 
ax1.spines['bottom'].set_color("#5998ff") 
 
ax1.spines['top'].set_color("#5998ff") 
 
ax1.spines['left'].set_color("#5998ff") 
 
ax1.spines['right'].set_color("#5998ff") 
 
    
 
def animate(i): 
 
    graph_data = open('SensorLog.csv','r').read() 
 
    dataArray = graph_data.split('\n') 
 

 
    xar=[] 
 
    yar=[] 
 
    
 
    for eachLine in dataArray: 
 
     if 'TimeStamp' not in eachLine: 
 
      if len(eachLine)>1: 
 
       t,rc,ant,prot,rssi,epc,temp,ten,powr,unpowr,inf=(eachLine.split(','))   
 
       time = datetime.strptime(t, '%m/%d/%Y %H:%M:%S.%f') 
 
       clock = time.strftime('%I:%M') 
 
       xs = matplotlib.dates.datestr2num(clock) 
 
       hfmt = matplotlib.dates.DateFormatter('%m/%d/%Y\n%I:%M:%S %p') 
 

 
#    Convert tension 
 
       tension = int(float(ten)*float(slope)+float(offset)) 
 
       
 
       xar.append(xs) 
 
       yar.append(tension) 
 
       
 
    ax1.clear() 
 
    
 
    ax1.grid(True, color='w') 
 

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

 
     
 
    ax1.tick_params(axis='y', colors='w') 
 
    ax1.tick_params(axis='x', colors='w') 
 
    ax1.xaxis.set_major_formatter(hfmt) 
 

 
    fig.autofmt_xdate() 
 
    
 
    ax1.plot (xar,yar, 'c', linewidth=2) 
 

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

parateデータは、異なる色のラインプロットと同じグラフ(共有x軸)に、アンテナ1及び2と、プロットそれぞれに引き込ま...私の試みはここにあるが、それは動作していない:

import matplotlib 
 
import matplotlib.pyplot as plt 
 
import matplotlib.animation as animation 
 
from datetime import datetime 
 
     
 
offset = -7.4954 
 
slope = 0.9548 
 

 
fig = plt.figure(facecolor='#07000d') 
 

 
ax1 = fig.add_subplot(111, axisbg='#07000d') 
 
ax2 = fig.add_subplot(111, axisbg='#07000d') 
 

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

 
ax2.spines['bottom'].set_color("#5998ff") 
 
ax2.spines['top'].set_color("#5998ff") 
 
ax2.spines['left'].set_color("#5998ff") 
 
ax2.spines['right'].set_color("#5998ff") 
 
    
 
def animate(i): 
 
    graph_data = open('SensorLog.csv','r').read() 
 
    dataArray = graph_data.split('\n') 
 

 
    xar=[] 
 
    yar=[] 
 
    xar2=[] 
 
    yar2=[]  
 

 
    for eachLine in dataArray: 
 
     if 'TimeStamp' not in eachLine: 
 
      if len(eachLine)>1: 
 
       t,rc,ant,prot,rssi,epc,temp,ten,powr,unpowr,inf=(eachLine.split(','))   
 
       time = datetime.strptime(t, '%m/%d/%Y %H:%M:%S.%f') 
 
       clock = time.strftime('%I:%M') 
 
       xs = matplotlib.dates.datestr2num(clock) 
 
       hfmt = matplotlib.dates.DateFormatter('%m/%d/%Y\n%I:%M:%S %p') 
 

 
#    Convert tension 
 
       tension = int(float(ten)*float(slope)+float(offset)) 
 
           
 
       if ant == '1': 
 
        xar.append(xs) 
 
        yar.append(tension) 
 
       
 
       if ant == '2': 
 
        xar2.append(xs)      
 
        yar2.append(tension) 
 
        
 
    ax1.clear() 
 
    ax2.clear() 
 
    
 
    ax1.grid(True, color='w') 
 
    ax2.grid(True, color='w') 
 

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

 
     
 
    ax1.tick_params(axis='y', colors='w') 
 
    ax1.tick_params(axis='x', colors='w') 
 
    ax1.xaxis.set_major_formatter(hfmt) 
 
    
 
    ax2.tick_params(axis='y', colors='w') 
 
    ax2.tick_params(axis='x', colors='w') 
 
    ax2.xaxis.set_major_formatter(hfmt) 
 
    
 
    fig.autofmt_xdate() 
 
    
 
    ax1.plot (xar,yar, 'c', linewidth=2) 
 
    ax2.plot (xar2,yar2,'r', linewidth=3) 
 

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

あなたは、私が正常にant 1とant 2のデータを分離し、同じ図形上に異なる色でプロットする方法についてのご意見はありますか?

答えて

0

同じ軸を使用して各データセットを単純にプロットすることができます。

次の方法では、defaultdict(list)とともに、データの読み込みを支援するためにPython csv.DictReaderを使用して、各行のアンテナに基づいてリストにデータを自動的に分割します。

これはまた、アドレスにコードを追加して互いに以上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() 

を出力の種類:

demo plot

+0

マーティン、これは素晴らしいです - 確かにこれで行くための正しい方法、ありがとう!今私は別の問題が発生していると私はPythonでこのCSV関数で解決することができると思う。 「成功した」読み取りであるデータの行には、11個の値(コンマで区切られた値)があります。しかし、センサーがアンテナから取り除かれた場合、11個の値すべてを返送しない迷い読みを得ることができ、「Ten」を読み取る際にエラーが発生します。 11の値を持たないcsv行を除外するためにIF文をどこに置くことができますか? – Jeffrey

+0

また、最後のデータポイントから少なくとも60秒が経過した場合、matplotlibが2つのデータポイントを同じアンテナから自動的にラインで接続するのを防ぐ方法がありますか?センサーが読み取り距離外に出て2分後に戻ってくると表示されるこの邪魔な補間直線を得ます。これは起こらなかった張力の増加を示しています。むしろこのデータギャップを空にするだけです。何か案は? – Jeffrey

+0

欠落した 'Ten'フィールドエントリをスキップするようにスクリプトを更新しました。 60秒を超えてデータを切断するには、データをグループ化し、グループごとにプロットを行う必要があります。 –

関連する問題