在seaborn factorplot

时间:2018-04-19 20:51:39

标签: python seaborn boxplot

我希望让每个箱子图上都显示样品编号,如下所示: 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()

Here is the plot

我希望得到" n:[观察次数]"正好位于中位数之上,我想知道是否有办法获得x-tick。此外,假设某些群体并不总是同时拥有男性和女性,因此它不能被硬编码。

1 个答案:

答案 0 :(得分:1)

这里有几件棘手的事情:

  1. 你有两个subaxes,每个主要情节一个。你需要遍历这些。

  2. 每个轴上有多个x偏移箱图。你需要考虑到这一点。

  3. 一旦你知道你在哪里画画,你需要知道哪个地块在那里可视化,因为订购(先是'是'或先是'否'?'男'先或'女'?)不保证。

  4. 幸运的是,如果你保持数据框的索引(或者,在这种情况下,多索引),你只需要时间,性别和吸烟的文本来获得正确的值。这些都可以通过一点挖掘获得。生成的代码如下所示(请注意对mediansnobs的更改):

    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')
    

    Resulting plot

    要验证,这是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