2011-10-07 104 views
19

我有一個看起來像這樣的數據樣本:繪製的matplotlib/gnuplot的標記間隔

a 10:15:22 10:15:30 OK 
b 10:15:23 10:15:28 OK 
c 10:16:00 10:17:10 FAILED 
b 10:16:30 10:16:50 OK 

我要的是通過以下方式繪製上述數據:

captions^
    | 
c |   *------* 
b | *---* *--* 
a | *--* 
    |___________________ 
        time > 

隨着線的顏色取決於數據點的狀態。標籤(a/b/c/...)可能會或可能不會重複。

在我從文檔收集了gnuplot的matplotlib,這種類型的曲線應該是更容易在後者做,因爲它不是一個標準的情節和需要一些預處理。

的問題是:

  1. 有沒有做這樣的地塊在任何工具的標準方式?
  2. 如果沒有,我應該如何去繪製這個數據(指針相關工具/文件/功能/實例做一些事情,有點狀這裏所描述的事情)?

回答

21

更新:現在包括處理數據樣本,並使用MPL日期的功能。

import matplotlib.pyplot as plt 
from matplotlib.dates import DateFormatter, MinuteLocator, SecondLocator 
import numpy as np 
from StringIO import StringIO 
import datetime as dt 

### The example data 
a=StringIO("""a 10:15:22 10:15:30 OK 
b 10:15:23 10:15:28 OK 
c 10:16:00 10:17:10 FAILED 
b 10:16:30 10:16:50 OK 
""") 

#Converts str into a datetime object. 
conv = lambda s: dt.datetime.strptime(s, '%H:%M:%S') 

#Use numpy to read the data in. 
data = np.genfromtxt(a, converters={1: conv, 2: conv}, 
        names=['caption', 'start', 'stop', 'state'], dtype=None) 
cap, start, stop = data['caption'], data['start'], data['stop'] 

#Check the status, because we paint all lines with the same color 
#together 
is_ok = (data['state'] == 'OK') 
not_ok = np.logical_not(is_ok) 

#Get unique captions and there indices and the inverse mapping 
captions, unique_idx, caption_inv = np.unique(cap, 1, 1) 

#Build y values from the number of unique captions. 
y = (caption_inv + 1)/float(len(captions) + 1) 

#Plot function 
def timelines(y, xstart, xstop, color='b'): 
    """Plot timelines at y from xstart to xstop with given color.""" 
    plt.hlines(y, xstart, xstop, color, lw=4) 
    plt.vlines(xstart, y+0.03, y-0.03, color, lw=2) 
    plt.vlines(xstop, y+0.03, y-0.03, color, lw=2) 

#Plot ok tl black  
timelines(y[is_ok], start[is_ok], stop[is_ok], 'k') 
#Plot fail tl red 
timelines(y[not_ok], start[not_ok], stop[not_ok], 'r') 

#Setup the plot 
ax = plt.gca() 
ax.xaxis_date() 
myFmt = DateFormatter('%H:%M:%S') 
ax.xaxis.set_major_formatter(myFmt) 
ax.xaxis.set_major_locator(SecondLocator(interval=20)) # used to be SecondLocator(0, interval=20) 

#To adjust the xlimits a timedelta is needed. 
delta = (stop.max() - start.min())/10 

plt.yticks(y[unique_idx], captions) 
plt.ylim(0,1) 
plt.xlim(start.min()-delta, stop.max()+delta) 
plt.xlabel('Time') 
plt.show() 

Resulting image

+0

謝謝。我已經成功使用您的解決方案繪製圖形作爲基礎。如果沒有人提出更好的解決方案,會接受你的答案。 – dm3

+0

我更新我的回答,我一直想學的matplotlibs日期功能。 – tillsten

+1

對於不同的結束符號,用分散符號替換vlines。 plt.scatter(xstart,y,s = 100,c = color,marker ='x',lw = 2,edgecolor = color) – tillsten