2014-03-06 120 views
6

假设我有一个过去90天里每天测量的值。我想绘制这些值的直方图,但我想让观看者容易看到过去90天内某些非重叠子集的测量结果。我想通过将直方图的每个小节“细分”为块来做到这一点。最早观察的一块,最近观察一块,最近观察一块。带有堆叠组件的直方图

这听起来像是df.plot(kind='bar', stacked=True)的工作,但我无法正确地获取详细信息。

这是我到目前为止有:

import numpy as np 
import pandas as pd 
import seaborn as sbn 

np.random.seed(0) 

data = pd.DataFrame({'values': np.random.randn(90)}) 
data['bin'] = pd.cut(data['values'], 15, labels=False) 
forhist = pd.DataFrame({'first70': data[:70].groupby('bin').count()['bin'], 
         'next15': data[70:85].groupby('bin').count()['bin'], 
         'last5': data[85:].groupby('bin').count()['bin']}) 

forhist.plot(kind='bar', stacked=True) 

这一点让我:

poor result

此图有一些不足之处:

  • 酒吧集聚于错误的顺序。 last5应位于顶部,中间位置应为next15。即它们应按照forhist中列的顺序进行堆叠。
  • 条形之间有水平间距
  • x轴标有整数而不是指示箱代表的值。我的“第一选择”是将x轴标记为与我刚运行data['values'].hist()时完全相同。如果我做了pd.cut(data['values'], 15),我的“第二选择”是将x轴标记为“bin名称”。在我的代码中,我使用了labels=False,因为如果我没有这样做,它会将条形边缘标签(作为字符串)用作条形标签,并且会将它们按字母顺序排列,从而使图形基本无用。

解决此问题的最佳方法是什么?我觉得我到目前为止使用了非常笨拙的功能。

回答

7

好吧,这里有一个方法,从matplotlibhist功能本身攻击它,使用特点:

fig, ax = plt.subplots(1, 1, figsize=(9, 5)) 
ax.hist([data.ix[low:high, 'values'] for low, high in [(0, 70), (70, 85), (85, 90)]], 
     bins=15, 
     stacked=True, 
     rwidth=1.0, 
     label=['first70', 'next15', 'last5']) 
ax.legend() 

其中给出:

better