Python:绘制seaborn条形图中的百分比

时间:2016-02-29 05:49:42

标签: python pandas bar-chart seaborn

对于数据框

import pandas as pd
df=pd.DataFrame({'group':list("AADABCBCCCD"),'Values':[1,0,1,0,1,0,0,1,0,1,0]})

我试图绘制一个条形图,显示A, B, C, D取零(或一)的百分比。

我有一个可行的方式,但我认为必须有更直接的方式

tempdf=df.groupby(['group','Values']).Values.count().unstack().fillna(0)
tempdf['total']=df['group'].value_counts()
tempdf['percent']=tempdf[0]/tempdf['total']*100

tempdf.reset_index(inplace=True)
print tempdf

sns.barplot(x='group',y='percent',data=tempdf)

如果它只绘制平均值,我可以在sns.barplot数据帧上执行df而不是tempdf。如果我对绘制百分比感兴趣,我不确定如何优雅地做到这一点。

谢谢,

4 个答案:

答案 0 :(得分:4)

您可以在sns.barplot estimator中使用自己的功能,从docs开始:

  

估算器:可映射矢量 - >标量,可选
  用于在每个分类箱内估计的统计函数。

对于您的情况,您可以将函数定义为lambda:

sns.barplot(x='group', y='Values', data=df, estimator=lambda x: sum(x==0)*100.0/len(x))

enter image description here

答案 1 :(得分:4)

您可以将Pandas与seaborn结合使用,以简化此操作:

import pandas as pd
import seaborn as sns

df = sns.load_dataset("tips")
x, y, hue = "day", "proportion", "sex"
hue_order = ["Male", "Female"]

(df[x]
 .groupby(df[hue])
 .value_counts(normalize=True)
 .rename(y)
 .reset_index()
 .pipe((sns.barplot, "data"), x=x, y=y, hue=hue))

enter image description here

答案 2 :(得分:2)

您可以按照以下步骤操作,以便可以在绘图中的条形上方看到计数和百分比。在下面查看示例输出

如果在绘图中具有“ hue”参数,则

with_hue 函数将在条形图上绘制百分比。它以实际图形,要素,要素中的类别数和色调类别(色调特征中的类别数)作为参数。

如果您具有正常图,

without_hue 函数将在条形图上绘制百分比。它以实际图形和特征为参数。

def with_hue(plot, feature, Number_of_categories, hue_categories):
    a = [p.get_height() for p in plot.patches]
    patch = [p for p in plot.patches]
    for i in range(Number_of_categories):
        total = feature.value_counts().values[i]
        for j in range(hue_categories):
            percentage = '{:.1f}%'.format(100 * a[(j*Number_of_categories + i)]/total)
            x = patch[(j*Number_of_categories + i)].get_x() + patch[(j*Number_of_categories + i)].get_width() / 2 - 0.15
            y = patch[(j*Number_of_categories + i)].get_y() + patch[(j*Number_of_categories + i)].get_height() 
            ax.annotate(percentage, (x, y), size = 12)
    plt.show()

def without_hue(plot, feature):
    total = len(feature)
    for p in ax.patches:
        percentage = '{:.1f}%'.format(100 * p.get_height()/total)
        x = p.get_x() + p.get_width() / 2 - 0.05
        y = p.get_y() + p.get_height()
        ax.annotate(percentage, (x, y), size = 12)
    plt.show()

enter image description here

enter image description here

答案 3 :(得分:0)

您可以使用Dexplot库,该库可以返回分类变量的相对频率。它具有与Seaborn类似的API。将您想要获得相对频率的列传递给agg参数。如果您想将其细分为另一列,请使用hue参数。以下返回原始计数。

import dexplot as dxp
dxp.aggplot(agg='group', data=df, hue='Values')

enter image description here

要获取相对频率,请将normalize参数设置为要标准化的列。使用'all'对总计数进行归一化。

dxp.aggplot(agg='group', data=df, hue='Values', normalize='group')

enter image description here

'Values'列上进行归一化将产生以下图形,其中所有“ 0”条的总数为1。

dxp.aggplot(agg='group', data=df, hue='Values', normalize='Values')

enter image description here