【问题标题】:How can I extract the bins from seaborn's KDE distplot object?如何从 seaborn 的 KDE distplot 对象中提取 bin?
【发布时间】:2020-06-16 03:09:50
【问题描述】:

背景

我正在尝试根据我在expression levels 中的数据对一种植物(拟南芥)的约 11,000 个基因进行分组,以响应光照。

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

所以而不是:

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

我有课堂输出:

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 源代码的内容,弄清楚他们如何在绘图之前对数据进行分类......但这远远超出了我的独角兽技能......

【问题讨论】:

  • distplot 是一个直方图,顶部有一个 kde 的图。那些是独立的。由于 KDE 没有“分组”,我不确定这个问题的真正目的是什么?
  • @ImportanceOfBeingErnest,感谢您的编辑。还有你更深层次的理解:我想问题是,什么算法决定了分箱,我想我可以四处寻找源代码的直方图部分。谢谢朋友!

标签: python grouping histogram seaborn discrete-mathematics


【解决方案1】:

Seaborn 调用pyplot.hist,而后者又调用numpy.histogram。因此,如果没有指定,可以检查 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)

【讨论】:

  • 很明显,您自己查看源代码已经超越了职责范围,这太棒了……作为 Stack 的新入门者,我真的无法相信你们所有人都有多大的帮助。我现在研究了 freedman diaconis 并了解了 IQR 依赖性。我尝试 +1,但我仍然
猜你喜欢
  • 2019-01-17
  • 2020-12-10
  • 2017-10-12
  • 2015-10-22
  • 2018-02-05
  • 2018-04-19
  • 2021-05-24
  • 2015-10-03
相关资源
最近更新 更多