2017-04-18 88 views
0

如何使用pandas和seaborn以「enabled」啓用色調來爲每個通道(inapp,email,push)繪製三個時間序列?請注意,這些列是MultiIndexed。我想要這些圖共享y軸,並且有一個共同的圖例來指示'enabled'的值。多索引DataFrame的分面圖

 
|---------|---------------|--------------|---------------| 
| channel | inapp   | email  | push   | 
| enabled | true | false | false | true | false | true | 
|---------|-------|-------|-------|------|-------|-------| 
| 0  | 0  | 80 | 28 | 0 | 5  | 0  | 
| 1  | 2  | 80 | 28 | 3 | 5  | 233 | 
| 2  | 4  | 80 | 28 | 7 | 5  | 587 | 
| 3  | 5  | 80 | 28 | 12 | 5  | 882 | 
| 4  | 7  | 86 | 28 | 16 | 5  | 1292 | 
|---------|-------|-------|-------|------|-------|-------| 
+0

'df.stack(水平= '通道')。管(seaborn.FacetGrid,...)。圖(...)' –

+0

@PaulH請你能提交的一個答案,因爲我還沒有得到它的工作呢?你可以借用安德魯的代碼。 – Emre

回答

1

這裏的另一種方式,用保羅轟的.stack()做法(雖然我也無法FacetGrid看着辦吧):

import pandas as pd 
from matplotlib import pyplot as plt 

enabled = [True, False] 
channel =['inapp','email','push'] 
values = [0,2,4,5,7,80,80,80,80,86,28,28,28,28,28, 
      0,3,7,12,16,5,5,5,5,5,0,233,587,882,1292] 
values = np.array(values).reshape((5,6), order='F') 

columns = pd.MultiIndex.from_product([channel,enabled], names=("channel","enabled")) 
df = pd.DataFrame(values, columns=columns) 

fig, ax = plt.subplots(1,3,sharey=True) 

for i, (key, group) in enumerate(df.stack(level='channel').reset_index(level=1).groupby('channel')): 
    group.plot(label=key, title=key, ax=ax[i]) 

UPDATE:
這裏有一個更緊湊,使用unstack()factorplot()
rename行只在那裏爲了繪圖清晰,可以將其刪除。

df = (df.unstack('enabled') 
     .reset_index() 
     .rename(columns={'level_2':'time',0:'value'}) 
) 
sns.factorplot(data=df, x='time', y='value', hue='enabled', col='channel') 

timeseries plot

+0

@Emre此更新的解決方案應滿足您的所有參數。如果這仍然不能令人滿意地回答您的問題,請告訴我缺少什麼。 –

1

Seaborn可能沒有必要。
這裏的代碼,構建您所指定的數據幀:

import pandas as pd 

enabled = [True, False] 
channel =['inapp','email','push'] 
values = [0,2,4,5,7,80,80,80,80,86,28,28,28,28,28, 
      0,3,7,12,16,5,5,5,5,5,0,233,587,882,1292] 
values = np.array(values).reshape((5,6), order='F') 

columns = pd.MultiIndex.from_product([channel,enabled], 
            names=("channel","enabled")) 
df = pd.DataFrame(values, columns=columns) 

channel inapp  email  push  
enabled True False True False True False 
0   0 80 28  0  5  0 
1   2 80 28  3  5 233 
2   4 80 28  7  5 587 
3   5 80 28 12  5 882 
4   7 86 28 16  5 1292 

假設你指的是由索引值0-4的時間序列,如果它是可以接受的與pyplot創造次要情節,下面的代碼將滿足您的要求:

from matplotlib import pyplot as plt 

fig, ax = plt.subplots(1, 3, sharey=True) 
for i, col in enumerate(channel): 
    df.T.xs(col).T.plot(ax=ax[i], xticks=df.index, title=col) 

panel plot

當然,換位有點體操。可能有熊貓福的方式來達到相同的效果,使用groupby(),但我玩了一下,並找不到解決方案。希望這可以幫助。