我如何从 seaborn 的 KDE distplot 对象中提取 bins?

How can I extract the bins from seaborn's KDE distplot object?

背景

我正在尝试根据我掌握的 expression levels 变化数据对一种植物(Arabidopsis thaliana)的约 11,000 个基因进行分组,以响应曝光。

每个基因的原始值是连续的随机变量,但我希望将这些值离散化为具有 20 个离散的 classes。

所以代替:

change_in_expression = array([-2.2, -1.1, -1.2, ...,  0.6, -1. , -0.9])

我有 class 个输出:

change_in_expression = array(["3_to_4","2_to_3","1_to_2",...])

我试过的

我用 seaborn's distplot() 绘制分布图,我相信它使用 KDE:

import seaborn as sns

d = array([-2.2, -1.1, -1.2, ...,  0.6, -1. , -0.9]) # = change_in_expression

dis = sns.distplot(d, fit=stats.laplace, kde=False)

plt.title("Distribution of Differential Expression")
plt.xlabel("Log2FoldChange in expression")
plt.ylabel("Frequency")
plt.show()

而且我知道 matplotlib.pyplot's hist() 允许您提取垃圾箱,当默认设置“自动”生成这些分组时...


总结性问题

问题是,我怎样才能对我的基因进行分组?这是一个比仅仅询问 matplotlib's hist()seaborn 版本更广泛的问题...因为 seaborn's distplot 使用 KDE.

通过查看可用的方法,我似乎无法从 seaborn 创建的 ax 对象中获取垃圾箱:

dir(sns.distplot(d, fit=stats.laplace, kde=False)

我想,一种方法是检查 seaborn 的 distplot 源代码的内部结构,弄清楚它们是如何在绘图之前对数据进行分类的……但这超出了我的独角兽技能范围。 .

Seaborn 调用 pyplot.hist,后者又调用 numpy.histogram。因此,如果指定了 none,可以检查 seaborn 使用什么作为 bins 参数。 IE。 a 是数据,

bins = min(_freedman_diaconis_bins(a), 50)

其中 1

def _freedman_diaconis_bins(a):
    """Calculate number of hist bins using Freedman-Diaconis rule."""
    # From https://stats.stackexchange.com/questions/798/
    a = np.asarray(a)
    if len(a) < 2:
        return 1
    h = 2 * iqr(a) / (len(a) ** (1 / 3))
    # fall back to sqrt(a) bins if iqr is 0
    if h == 0:
        return int(np.sqrt(a.size))
    else:
        return int(np.ceil((a.max() - a.min()) / h))

iqr2

def iqr(a):
    """Calculate the IQR for an array of numbers."""
    a = np.asarray(a)
    q1 = stats.scoreatpercentile(a, 25)
    q3 = stats.scoreatpercentile(a, 75)
    return q3 - q1

所有这些应该与

大致相同
bins = min(len(numpy.histogram_bin_edges(a, bins="fd")), 50)

bins = 50 if len(numpy.histogram_bin_edges(a, bins="fd")) > 50 else "fd"

然后将 bins 传递给 pyplot.hist

plt.hist(a, bins=bins)