我如何从 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))
和iqr
2
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)
背景
我正在尝试根据我掌握的 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))
和iqr
2
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)