如何在Seaborn条形图中添加观察数量?

时间:2018-03-16 06:25:37

标签: python bar-chart seaborn

我想在Seaborn条形图中添加观察数量。我创建了一个带有四个条形的条形图,它们代表y轴上的百分比。我想在每个条上添加一个标签,显示观察次数。

在我的代码中,第一个块创建了条形图。

我从其他地方的例子中创建了第二个代码块。我收到一条错误消息,指向以" medians开头的行,"并且消息说:AttributeError:' float'对象没有属性'值'

sns.set_style("whitegrid")
ax = sns.barplot(x=barplot_x, y="trump_margin_pct", 
data=mean_analysis)
sns.palplot(sns.diverging_palette(240, 0))
ax.set(xlabel='Strength of Candidate Support', ylabel='Average Trump 
Margin of Victory/(Loss) (in %)')  
ax.set_title('Average Strength of Candidate Support Across Groups of 
Counties, 2016')

# Calculate number of obs per group & median to position labels
medians = mean_analysis['trump_margin_pct'].median().values
nobs = mean_analysis['trump_margin_pct'].value_counts().values
nobs = [str(x) for x in nobs.tolist()]
nobs = ["n: " + i for i in nobs]

# Add it to the plot
pos = range(len(nobs))
for tick,label in zip(pos,ax.get_xticklabels()):
     ax.text(pos[tick], medians[tick] + 0.03, nobs[tick],
horizontalalignment='center', size='x-small', color='w', 
weight='semibold')

1 个答案:

答案 0 :(得分:0)

你的方法几乎是正确的。但是,您计算整个数据mean_analysis['trump_margin_pct']而不是组的观察值的中位数和数量。这会导致您的错误。您可以使用groupby来计算群组
平均:
只需添加groupby即可计算出中位数。

medians = mean_analysis.groupby(['barplot_x'])['trump_margin_pct'].median().values


数量:
对于obervations的数量,您必须计算分组的聚合值计数。这就是你如何做到的。

nobs = mean_analysis.groupby(['barplot_x'])['trump_margin_pct'].agg(['count'])
nobs = ["n: " + str(i) for s in nobs.values for i in s]


示例:
我使用了一些虚拟数据来重新创建你的例子。

import seaborn as sns

sns.set_style("whitegrid")
tips = sns.load_dataset("tips")
ax = sns.barplot(x="day", y="total_bill", data=tips)
ax.set(xlabel='Strength of Candidate Support', ylabel='Average Trump Margin of Victory/(Loss) (in %)')  
ax.set_title('Average Strength of Candidate Support Across Groups of Counties, 2016')

medians = tips.groupby(['day'])['total_bill'].median().values
nobs = tips.groupby(['day'])['total_bill'].agg(['count'])
nobs = ["n: " + str(i) for s in nobs.values for i in s]

pos = range(len(nobs))
for tick,label in zip(pos,ax.get_xticklabels()):
    ax.text(pos[tick], medians[tick] + 0.03, nobs[tick], horizontalalignment='center', size='x-small', color='w', weight='semibold')

enter image description here