如何更好地适应 seaborn 小提琴情节?

Posted

技术标签:

【中文标题】如何更好地适应 seaborn 小提琴情节?【英文标题】:How to better fit seaborn violinplots? 【发布时间】:2015-03-22 19:55:57 【问题描述】:

下面的代码给了我一个非常漂亮的小提琴图(和里面的箱线图)。

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

foo = np.random.rand(100)
sns.violinplot(foo)
plt.boxplot(foo)
plt.show()

到目前为止一切顺利。但是,当我查看foo 时,该变量不包含任何负值。 seaborn 情节在这里似乎具有误导性。正常的 matplotlib 箱线图给出的结果更接近我的预期。

如何制作更合适的小提琴图(不显示假负值)?

【问题讨论】:

嗯,这可能并不容易。这是 KDE 的人工制品,它不知道 0 处有硬边界。如果您对此问题感兴趣,另请参阅:stats.stackexchange.com/questions/65866/… @cel 谢谢。这就是我的想法。但是就不能更紧一点吗? 有算法。在这个答案中看到令人印象深刻的结果:stats.stackexchange.com/a/71291。但是我还没有在python中看到它。 【参考方案1】:

正如 cmets 所指出的,这是基于高斯 KDE 的假设的结果(我不确定我是否会称其为“人工制品”)。正如已经提到的,这在某种程度上是不可避免的,如果您的数据不符合这些假设,您最好只使用箱线图,它只显示实际数据中存在的点。

但是,在您的回复中,您询问它是否可以“更紧”,这可能意味着一些事情。

一个答案可能是改变平滑内核的带宽。您可以使用 bw 参数来做到这一点,这实际上是一个比例因子;将使用的带宽是bw * data.std():

data = np.random.rand(100)
sns.violinplot(y=data, bw=.1)

另一个答案可能是在数据点的极端处截断小提琴。 KDE 仍将适合超出数据边界的密度,但不会显示尾部。您可以使用cut 参数来执行此操作,该参数指定应绘制密度超过极值的带宽单位数。要截断,请将其设置为 0:

sns.violinplot(y=data, cut=0)

顺便说一句,violinplot 的 API 在 0.6 中是 going to change,我在这里使用的是开发版本,但 bwcut 参数都存在于当前发布的版本中并且表现得更多或更少相同的方式。

【讨论】:

我不喜欢使用cut 的解决方案。它隐藏了KDE 无法正确适应这种密度的事实。接近边界 0 的密度具有误导性,因为即使相应的直方图的最大值为 0,您也会得到这样的密度估计。 在github.com/mwaskom/seaborn/issues/525 上查看功能请求(等待 statsmodels 的上游更改)。 +1 很好的解决方案。这是一个快速而干净的解决方案。很明显,极端削减将表明 kde 和底层密度之间存在一些极端差异。

以上是关于如何更好地适应 seaborn 小提琴情节?的主要内容,如果未能解决你的问题,请参考以下文章

plotly vs seaborn:python中的小提琴情节

python Seaborn - 制作叠加的beeswarm和小提琴情节

如何在seaborn小提琴图中为每个组分配不同的位置

如何忽略海底小提琴情节中的异常值? [复制]

如何手动缩放 Seaborn Violinplot 的计数

Seaborn violinplots:如何获得小提琴边缘的线条路径?