2014-07-17 127 views
0

我是matplotlib的新手,請原諒我的無知並幫我解決這個問題。本質上,我有一個CSV文件中的其他Python腳本正在生成以下數據。針對同一圖形中matplotlib中不同時間戳的多個X值繪製多個Y值?

CSV1: 時間戳,DATA1

23:04:17, 1163557.14 bps 
23:04:27, 1137578.47 bps 
23:04:37, 1139094.66 bps 
23:04:47, 1095752.97 bps 
23:04:57, 1264145.01 bps 

CSV2: 時間戳,DATA2

23:04:21, 1011000.00 bps 
23:04:31, 1011000.00 bps 
23:04:41, 1011000.00 bps 
23:04:51, 1014000.00 bps 
23:05:01, 1008000.00 bps 

CSV3: 時間戳,DATA3

23:05:28, 1109617.96 bps 
23:05:38, 1139177.95 bps 
23:05:48, 1108110.09 bps 
23:05:58, 1107078.94 bps 
23:06:08, 1163406.80 bps 

我想要的是沿X軸有時間運行,沿Y軸有三個Y值,分別顯示「data1」,「data2」和「data3」。數據每10秒收集一次,但不一定同步。所以我不能有一個單一的X軸陣列。但我希望所有這些在同一個圖表中進行比較。我怎麼解決這個問題 ?

任何示例代碼或導致文檔將不勝感激。

**編輯:

基本上我的問題是,數據被索引沿不同的時戳,但我要繪製THEM在同一圖表上。我該怎麼做**

編輯2:

謝謝你們爲輸入。這真的有幫助。因此,這是代碼我現在有:

import csv 
    import sys 
    import datetime 
    import random 
    import matplotlib.pyplot as plt 
    from matplotlib.dates import MinuteLocator, SecondLocator, DateFormatter 

    time_e_z_raw_list = [] 
    bitrate_e_z_list = [] 
    time_i_z_raw_list = [] 
    bitrate_i_z_list = [] 
    time_i_query_z_raw_list = [] 
    bitrate_i_q_z_raw_list = [] 

    f_enc_z = open(sys.argv[1], 'rt') 
    f_ing_z = open(sys.argv[2], 'rt') 
    f_ing_q_z = open(sys.argv[3], 'rt') 

    try: 
     reader1 = csv.reader(f_enc_z) 
     for row in reader1: 
      bitrate = row[1] 
      time_e_z_raw_list.append(row[0]) 
      bitrate_e_z_list.append(bitrate[:-4]) 
     reader3 = csv.reader(f_ing_z) 
     for row in reader3: 
      bitrate = row[1] 
      time_i_z_raw_list.append(row[0]) 
      bitrate_i_z_list.append(bitrate[:-4]) 
     reader4 = csv.reader(f_ing_q_z) 
     for row in reader4: 
      bitrate = row[1] 
      time_i_q_z_raw_list.append(row[0]) 
      bitrate_i_q_z_raw_list.append(bitrate[:-4]) 

    finally: 
     f_enc_z.close() 
     f_ing_z.close() 
     f_ing_q_z.close() 

    time_e_z_list = [datetime.datetime.strptime(s, '%H:%M:%S') for s in   time_e_z_raw_list] 
    time_i_z_list = [datetime.datetime.strptime(s, '%H:%M:%S') for s in  time_i_z_raw_list] 
    time_i_q_z_list = [datetime.datetime.strptime(s, '%H:%M:%S') for s in time_i_q_z_raw_list] 

    fig = plt.figure(figsize=(18,16)) 

    plt.plot(time_e_z_list, bitrate_e_z_list, label="label1", lw=1) 
    plt.plot(time_i_z_list, bitrate_i_z_list, label="label2", lw=1) 
    plt.plot(time_i_q_z_list, bitrate_i_z_list, label="label3", lw=1) 

    minutes = MinuteLocator() 
    seconds = SecondLocator() 

    ax = plt.gca() 
    ax.xaxis.set_major_locator(minutes) 
    ax.xaxis.set_minor_locator(seconds) 
    ax.xaxis.set_major_formatter(DateFormatter("%H:%M:%S")) 
    plt.xlabel('time') 
    plt.ylabel('bitrate in bps') 
    plt.grid() 
    plt.legend(loc='upper right') 

    plt.gcf().autofmt_xdate() 

    plt.show() 

麻煩的是,當我有一個範圍超過3小時以上的時間戳,圖形被扭曲得到。我如何確保X軸顯示的範圍根據我採樣的時間戳範圍動態調整?通常,我每20秒運行4個小時以上的數據點。所以,當我繪製我得到一個非常糟糕的圖。我如何解決它 ?但是,當我有少量數據時,我會得到一個適當的圖表。

回答

2

好吧,我更新了我最初的答案。這是一個可能的解決方案。但是既然你在談論一個CSV文件,你可能想看看熊貓的時間系列。

import datetime 
import random 
import matplotlib.pyplot as plt 

data1 = (1163557.14, 1137578.47, 1139094.66) 
times1_raw = ('23:04:17', '23:04:27', '23:04:37') 
times1 = [datetime.datetime.strptime(s, '%H:%M:%S') for s in times1_raw] 

data2 = (1011000.00, 1011000.00, 1011000.00) 
times2_raw = ('23:04:21', '23:04:31', '23:04:41') 
times2 = [datetime.datetime.strptime(s, '%H:%M:%S') for s in times2_raw] 

fig = plt.figure(figsize=(8,6)) 

plt.plot(times1, data1, label='data1', lw=2, marker='o') 
plt.plot(times2, data2, label='data2', lw=2, marker='s') 
plt.xlabel('time in seconds') 
plt.ylabel('speed in bps') 
plt.grid() 
plt.legend(loc='upper right') 

plt.gcf().autofmt_xdate() 

plt.show() 

enter image description here

+0

我會非常想擁有完整的時間戳太。所以我希望時間戳沿着X軸運行。只要data1和data2的數據點關閉幾秒鐘。是否有可能在X軸上有時間戳? – rajath26

+0

很高興聽到。也許你可以提供一些圖像來顯示這個問題實際上看起來如何 – Sebastian

0

這是我會怎麼解決這個問題。

首先,嘗試利用datetime模塊。處理帶時間戳的數據時可以節省時間。

我們知道時間步長的最小增量是一秒。所以我們首先製作一個包含所有可能時間的列表。

import matplotlib.pyplot as plt 
import datetime 

start_date = datetime.datetime(2014,6,17,23,4,17) 
end_date = datetime.datetime(2014,6,17,23,6,8) 
number_seconds = (end_date - start_date).seconds 

time_stamps = [start_date + datetime.timedelta(seconds=t) for t in range(number_seconds)] 

現在列表time_stampsdatetime對象,我想你只想小時:分鐘:基於您的樣本數據郵票第二。我們可以很容易地與一個以上列表理解:

time_stamps_fmt = [datetime.datetime.strftime(t,'%H:%m:%S') for t in time_stamps] 

現在,讓我們創建一個空數組存儲bps的數據:

bps_1 = np.zeros([number_seconds],dtype('float')) 
bps_2 = np.zeros([number_seconds],dtype('float')) 
bps_3 = np.zeros([number_seconds],dtype('float')) 

然後填充的bps_1/2/3對應的指數在時間戳。 csv文件。如果未找到時間戳,請爲該索引插入np.nan,matplotlib應將其視爲缺失值並且不繪製任何內容。

可以使用xticks顯示時間標記爲x-標籤:

plt.xticks(np.arange(number_seconds), time_stamps_fmt) 
+0

這是一個有趣的方式,你建議@ N1B4。但是如果我運行了4個多小時,你認爲通過索引每秒會有所幫助嗎? – rajath26

+0

您必須至少以一秒爲間隔存儲數據,因爲這是包含所有數據的最小頻率。但是你需要繪製每個數據點嗎?分鐘平均值如何?還是10分鐘的平均水平? – N1B4

相關問題