Pandas 多索引数据帧的分面图

Pandas 多索引数据帧的分面图,pandas,seaborn,Pandas,Seaborn,如何绘制每个频道(inapp、电子邮件、推送)的三个时间序列,色调随“启用”使用熊猫和seaborn而变化?请注意,这些列是多索引的。我希望绘图共享y轴,并有一个通用图例来指示“启用”的值 |---------|---------------|--------------|---------------| | channel | inapp | email | push | | enabled | true | false | false | t

如何绘制每个频道(inapp、电子邮件、推送)的三个时间序列,色调随“启用”使用熊猫和seaborn而变化?请注意,这些列是多索引的。我希望绘图共享y轴,并有一个通用图例来指示“启用”的值

|---------|---------------|--------------|---------------| | 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 | |---------|-------|-------|-------|------|-------|-------| |---------|---------------|--------------|---------------| |频道| inapp |电子邮件|推送| |启用|真|假|假|真|假|真| |---------|-------|-------|-------|------|-------|-------| | 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 | |---------|-------|-------|-------|------|-------|-------|
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)


当然,换位有点像体操。使用
groupby()
,可能有其他方法可以达到同样的效果,但我对此做了一些尝试,没有找到解决方案。希望这能有所帮助。

这里有另一种方法,使用Paul H的
.stack()
方法(尽管我也无法用
FaceGrid
来理解它):

更新:
这里有一个更紧凑的版本,使用
unstack()
factorplot()

重命名
行仅在其中,为了打印清晰,可以将其删除

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')

df.stack(level='channel').pipe(seaborn.FacetGrid,…).map(…)
@PaulH你能把它作为一个答案提交给我吗,因为我还没有让它工作?您可以借用andrew的代码。@Emre此更新的解决方案应满足您的所有参数。如果这仍然不能令人满意地回答您的问题,请告诉我缺少什么。
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')