首页 > 解决方案 > 在 Python 中使用汇总统计量绘制分面条形图

问题描述

有没有一种简洁的方法可以将 Python 中的汇总统计数据绘制为箱线图?下面的代码给出了每个平均值的条形图,我想将每个条形图交换为箱线图。

我意识到我不需要总结,但是使用真实数据,仅绘制其中一个框需要很长时间(即使使用showfliers=False);我不需要查看异常值,我还想为每个“pc”添加一个“population-wide”栏(即跨所有集群)(对此的任何建议将不胜感激..我再次尝试从 R 迁移到 python,仅仅得到这几行代码就花了足够长的时间)

import matplotlib.pyplot as plt
import seaborn as sns
out = pd.DataFrame({'cluster':['a']*100+['b']*100,
                         'pc': ['w', 'x', 'y', 'z']*50,
                         'value': np.random.normal(size=200)})
grouped = out.groupby(['cluster', 'pc'])
out = grouped.describe()
out = out.reset_index()
out.columns = [e[0] if e[0] != 'value' else e[1] for e in out.columns.tolist()]

#sns.catplot(x='cluster', y='mean', col='pc', kind='bar', data=out)
g = sns.FacetGrid(out, col="pc", col_wrap = 2)
g = g.map(plt.bar, "cluster", "mean")

在此处输入图像描述

标签: pythonbar-chartseaborn

解决方案


您可以使用Axes.bxp().从汇总统计中绘制箱线图。这需要封装在传递给的自定义绘图函数中map()

def my_bxp(**kwargs):
    ax = plt.gca()
    data = kwargs.pop('data')
    color = kwargs.pop('color')
    bxpstats = []
    for _,row in data.iterrows():
        print(row)
        d = {'med': row.loc['50%'],
             'q1': row.loc['25%'],
             'q3': row.loc['75%'],
             'whislo': row.loc['min'],
             'whishi': row.loc['max'],
             'label': row.loc['cluster']}
        bxpstats.append(d)
    ax.bxp(bxpstats, showfliers=False, boxprops=dict(color=color), 
                                       whiskerprops=dict(color=color), 
                                       capprops=dict(color=color))
    

g = sns.FacetGrid(out, col="pc", col_wrap = 2)
g = g.map_dataframe(my_bxp)

在此处输入图像描述

请注意,为简单起见,我将胡须从最小值延伸到最大值,这不是通常的表示。如果这是您想要的,您可能必须在计算汇总统计数据时计算适当的胡须范围。


推荐阅读