2014-10-22 3 views
4

타임 스탬프 (start)가 포함 된 열과 기간을 나타내는 timedeltas (duration)가 포함 된 열이 포함 된 팬더 데이터 프레임이 있습니다.timedelta가 막대 가로로 표시된 막대 그래프

나는 타임 라인에서 왼쪽 가장자리에이 지속 시간을 보여주는 가로 막 대형 차트를 플로팅하려고합니다. 나는 어쨌든 그것을하는 온라인 발견하지 못했습니다. 이것을 달성 할 수있는 방법이 있습니까?

지금까지, 이것은 내가 작동하지 않는, 무엇을 가지고 :

height = np.ones(df.shape[0]) 
    width = [x for x in df['duration']] 
    plt.bar(left=df['start'], height=height, width=width) 

편집 : 그 제외한 다음과 같이 나는이 문제가 해결되지 않는 폭을 업데이트 한 :

width = [x.total_seconds()/(60*1200) for x in df['duration']] 

나는 datetime 객체가 x 축으로 사용 할 수 있기 때문에 datetime.timedelta 개체, width에서 사용할 수 있는지 여부를 알고에 관심이 있어요. 그리고 그렇지 않다면 어떤 대안이 있습니까?

편집 # 2 :

이 내 질문에 대한 정확한 답변을하지 않을 수 있지만, 내가 생각했던 목적을 해결했다. 누구든지 관심이 들어,이 마침내했다 접근법이다 (나는이 목적을 위해 end를 만들기 위해 startduration을 사용) :

for i in range(df.shape[0]): 
     plt.axvspan(df.ix[i, 'start'], df.ix[i, 'end'], facecolor='g', alpha=0.3) 
     plt.axvline(x=df.ix[i, 'start'], ymin=0.0, ymax=1.0, color='r', linewidth=1) 
     plt.axvline(x=df.ix[i, 'end'], ymin=0.0, ymax=1.0, color='r', linewidth=1) 

답변

2

당신의 df.duration[0]의 유형 pandas.tslib.Timedelta하고 당신의 timestamps이 일 떨어져 당신이 사용할 수있는 경우 :

width = [x.days for x in df.duration] 

그러면 차트가 생성됩니다. this answer

UPDATE에 설명 된대로

그렇지 않으면 total_seconds 방법을 사용하십시오

데이터가 원하는 차트를 가지고있는 분 timedeltas 다음 하나의 방법으로 시간당 경우는이 같다 :

import datetime as dt 
import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 

dates = pd.date_range(start=dt.date(2014,10,22), periods=10, freq='H') 
df = pd.DataFrame({'start': dates, 'duration': np.random.randint(1, 10, len(dates))}, 
        columns=['start', 'duration']) 
df['duration'] = df.duration.map(lambda x: pd.datetools.timedelta(0, 0, 0, 0, x)) 
df.ix[1, 1] = pd.datetools.timedelta(0, 0, 0, 0, 30) # To clearly see the effect at 01:00:00 
width=[x.minutes/24.0/60.0 for x in df.duration] # mpl will treat x.minutes as days hense /24/60. 
plt.bar(left=df.start, width=width, height=[1]*df.start.shape[0]) 
ax = plt.gca() 
_ = plt.setp(ax.get_xticklabels(), rotation=45) 

그러면 다음과 같은 차트가 생성됩니다.

enter image description here

+0

감사합니다. 사실, 그들은 단지 몇 분 또는 몇 분만에 떨어져 있고 나는'total_seconds'로 다른 답을 보았습니다. 그러나 그것은 작동하지 않을 것입니다. 그 이유는 시간과 분으로 스케일링해야하지만 시간의 길이가 다르기 때문에이 스케일링은 정확하지 않으며 매번 수동으로 조정해야합니다. 그래서 지금은 너비가 입니다. df [ 'duration']의 x에 대해 width = [x.total_seconds()/(60 * 1200)] 'Pyplot'은 x 축에 대해'datetime' 객체를 처리하기 때문에 저는 'datetime.timedelta'가 너비에 대해 인식되고 처리 될 것으로 기대하고 있으며, 나는 그렇지 않다는 것에 놀랐습니다. – oxtay

+0

@oxtay 그렇습니다.'matplotlib'가'bar'와'broken_barh' 플롯 모두에서 TimeDeltas 또는 Offset을 기본적으로 이해한다면 더 좋을 것입니다. 그러나 그때까지는 당신이 원하는 것을 성취하기위한 다소 성가신 방법이 있습니다. 위의 게시물을 업데이트하여 시간/분을 포함하는 예를 보여주었습니다. – Primer

+0

@Primer 'dates'선언에 대한 datetime 가져 오기가 누락되었으므로이 기능이 작동하지 않는다는 점에 유의하십시오.'datetime.timedelta'가하는 것과 같은 메소드를 가지고 있지 않은'numpy.timedelta64'로 끝나기 때문에 판다 (pandas) 버전의 까다 롭습니다. – Ajean