我希望让每个箱子图上都显示样品编号,如下所示: https://python-graph-gallery.com/38-show-number-of-observation-on-boxplot/
我能够获得中位数和列表中的计数,如上面的链接所示。 但是,我有一个带有色调的factorplot,这样x-ticks的位置似乎不会被捕获在x轴上。
使用seaborn tips数据集,我有以下内容:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
sns.set_style("whitegrid")
tips = sns.load_dataset("tips")
g = sns.factorplot(x="sex", y="total_bill",hue="smoker",
col="time",data=tips, kind="box",size=4, aspect=.7)
# Calculate number of obs per group & median to position labels
medians = tips.groupby(['time','sex','smoker'])['total_bill'].median().values
nobs = tips.groupby(['time','sex','smoker']).size()
nobs = [str(x) for x in nobs.tolist()]
nobs = ["n: " + i for i in nobs]
plt.show()
我希望得到" n:[观察次数]"正好位于中位数之上,我想知道是否有办法获得x-tick。此外,假设某些群体并不总是同时拥有男性和女性,因此它不能被硬编码。
答案 0 :(得分:1)
这里有几件棘手的事情:
你有两个subaxes,每个主要情节一个。你需要遍历这些。
每个轴上有多个x偏移箱图。你需要考虑到这一点。
一旦你知道你在哪里画画,你需要知道哪个地块在那里可视化,因为订购(先是'是'或先是'否'?'男'先或'女'?)不保证。
幸运的是,如果你保持数据框的索引(或者,在这种情况下,多索引),你只需要时间,性别和吸烟的文本来获得正确的值。这些都可以通过一点挖掘获得。生成的代码如下所示(请注意对medians
和nobs
的更改):
medians = tips.groupby(['time','sex','smoker'])['total_bill'].median()
nobs = tips.groupby(['time','sex','smoker']).apply(lambda x: 'n: {}'.format(len(x)))
for ax in plt.gcf().axes:
ax_time = ax.get_title().partition(' = ')[-1]
for tick, label in enumerate(ax.get_xticklabels()):
ax_sex = label.get_text()
for j, ax_smoker in enumerate(ax.get_legend_handles_labels()[1]):
x_offset = (j - 0.5) * 2/5
med_val = medians[ax_time, ax_sex, ax_smoker]
num = nobs[ax_time, ax_sex, ax_smoker]
ax.text(tick + x_offset, med_val + 0.1, num,
horizontalalignment='center', size='x-small', color='w', weight='semibold')
要验证,这是nobs
系列:
time sex smoker
Lunch Male Yes n: 13
No n: 20
Female Yes n: 10
No n: 25
Dinner Male Yes n: 47
No n: 77
Female Yes n: 23
No n: 29