与seaborn的kdeplot

时间:2016-06-20 21:43:40

标签: python matplotlib visualization seaborn

下面的lineslist代表一组线(对于某些化学光谱,比如说),以MHz为单位。我知道用于探测这些线的激光器的线宽为5 MHz。因此,天真地,带宽为5的这些线的核密度估计应该给我在使用上述激光器的实验中产生的连续分布。

以下代码:

import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
lineslist=np.array([-153.3048645 ,  -75.71982528,  -12.1897835 ,  -73.94903264,
   -178.14293936, -123.51339541, -118.11826988,  -50.19812838,
    -43.69282206,  -34.21268228])
sns.kdeplot(lineslist, shade=True, color="r",bw=5)
plt.show()

产量

Predicted continuous experimental spectrum, based on theoretical lines, bandwidth=5 MHz

看起来像高斯,带宽远大于5 MHz。

我猜测由于某种原因,kdeplot的带宽与图本身的不同。最高和最低线之间的间隔约为170.0 MHz。假设我需要通过这个因素重新调整带宽:

import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
lineslist=np.array([-153.3048645 ,  -75.71982528,  -12.1897835 ,  -73.94903264,
   -178.14293936, -123.51339541, -118.11826988,  -50.19812838,
    -43.69282206,  -34.21268228])
sns.kdeplot(lineslist, shade=True, color="r",bw=5/(np.max(lineslist)-np.min(lineslist)))
plt.show()

我得到: enter image description here

线条似乎具有预期的5 MHz带宽。

就像那个解决方案一样花花公子,我把它从我的屁股中拉出来,我很好奇是否有人更熟悉seaborn的kdeplot内部可以评论为什么会这样。

谢谢,

塞缪尔

1 个答案:

答案 0 :(得分:5)

有一点需要注意的是,Seaborn实际上并没有自己处理带宽 - 它会将设置或多或少地传递给SciPy或Statsmodels软件包,具体取决于您安装的内容。 (它更喜欢Statsmodels,但会回到SciPy。)

各种子包中此参数的文档有点令人困惑,但据我所知,这里的关键问题是SciPy的设置是带宽因子,而不是带宽本身。也就是说,这个因子(有效地)乘以您绘制的数据的标准偏差,以便为您提供内核中使用的实际带宽。

因此,对于SciPy,如果您有一个固定的数字要用作带宽,则需要除以数据标准偏差。如果您尝试一致地绘制多个数据集,则需要调整每个数据集的标准偏差。这种调整有效地通过按范围缩放所做的 - 但同样,它不是所用数字的数据范围,而是数据的标准偏差。

为了让事情变得更加混乱,Statsmodels在给定标量值时期望真正的带宽,而不是乘以样本标准差的因子。因此,根据您使用的后端,Seaborn的行为会有所不同。没有直接告诉Seaborn后端使用的方法 - 最好的测试方法可能是尝试import statsmodels,看看是否成功(直接带宽)或失败(带宽 factor )。

顺便说一下,这些结果是针对Seaborn 0.7.0版进行测试的 - 我希望(希望?)未来的版本可能会改变这种行为。