2011-10-07 38 views
19

Tôi có một mẫu dữ liệu mà trông như thế này:Vẽ khoảng dán nhãn 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 

Những gì tôi muốn là để vẽ các dữ liệu trên theo cách sau:

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

Với sự màu sắc của các dòng phụ thuộc vào trạng thái OK/FAILED của điểm dữ liệu. Nhãn (a/b/c/...) có thể hoặc không lặp lại được.

Như tôi đã thu thập được từ tài liệu cho gnuplotmatplotlib, loại này của một âm mưu nên dễ dàng hơn để làm trong sau này vì nó không phải là một âm mưu tiêu chuẩn và sẽ đòi hỏi một số tiền xử lý.

Câu hỏi đặt ra là:

  1. Có một cách tiêu chuẩn để làm âm mưu như thế này trong bất kỳ công cụ?
  2. Nếu không, làm thế nào tôi nên đi về âm mưu dữ liệu này (con trỏ đến các công cụ có liên quan/tài liệu/chức năng/ví dụ mà làm điều gì đó giống như mô tả ở đây)?

Trả lời

21

Đã cập nhật: Bây giờ bao gồm xử lý mẫu dữ liệu và sử dụng chức năng ngày tháng 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

Cảm ơn. Tôi đã vẽ thành công một biểu đồ bằng cách sử dụng giải pháp của bạn làm cơ sở. Sẽ chấp nhận câu trả lời của bạn nếu không có ai đề xuất một giải pháp tốt hơn. – dm3

+0

Tôi đã cập nhật câu trả lời của mình, tôi luôn muốn tìm hiểu chức năng ngày matplotlibs. – tillsten

+1

Đối với các biểu tượng kết thúc khác nhau, bạn thay thế các vlines bằng các biểu tượng phân tán. plt.scatter (xstart, y, s = 100, c = màu, điểm đánh dấu = 'x', lw = 2, edgecolor = color) – tillsten

Các vấn đề liên quan