【发布时间】:2016-02-05 13:21:39
【问题描述】:
我对 seaborn 完全陌生,如果这是一个简单的问题,我深表歉意,但我在文档中的任何地方都找不到关于如何在 kdeplot 中控制 n_levels 绘制的级别的描述。这是一个例子:
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
x,y=np.random.randn(2,10000)
fig,ax=plt.subplots()
sns.kdeplot(x,y, shade=True,shade_lowest=False, ax=ax,n_levels=3,cmap="Reds")
plt.show()
这是结果图:
我希望能够知道显示的置信水平,以便我可以将我的图标记为“阴影区域显示 (a,b,c) 百分比置信区间”。我会天真地假设 n_levels 在某种程度上与高斯中的等效“sigmas”相关,但从示例中看起来并非如此。
理想情况下,我希望能够通过将元组传递给 kdeplot 来指定显示的间隔,例如:
levels=[68,95,99]
并绘制这些置信区域。
编辑:感谢@Goyo 和@tom,我想我可以澄清我的问题,并在我正在寻找的答案中找到答案。正如所指出的,n_levels 以levels 的形式传递给plt.cotourf,因此可以传递一个列表。但是sns.kdeplot 绘制了 PDF,并且 PDF 中的值与我正在寻找的置信区间不对应(因为这些对应于 PDF 的集成)。
我需要做的是传递sns.kdeplot 集成(和规范化)PDF 的x,y 值,然后我将能够输入例如n_levels=[0.68,0.95,0.99,1]。
编辑 2:我现在已经解决了这个问题。见下文。我使用 2d 标准化直方图来定义置信区间,然后我将其作为水平传递给标准化 kde 图。抱歉重复了,我可以做一个函数来返回级别,但我明确地把它全部输入了。
import numpy as np
import scipy.optimize
import matplotlib.pyplot as plt
import seaborn as sns
# Generate some random data
x,y=np.random.randn(2,100000)
# Make a 2d normed histogram
H,xedges,yedges=np.histogram2d(x,y,bins=40,normed=True)
norm=H.sum() # Find the norm of the sum
# Set contour levels
contour1=0.99
contour2=0.95
contour3=0.68
# Set target levels as percentage of norm
target1 = norm*contour1
target2 = norm*contour2
target3 = norm*contour3
# Take histogram bin membership as proportional to Likelihood
# This is true when data comes from a Markovian process
def objective(limit, target):
w = np.where(H>limit)
count = H[w]
return count.sum() - target
# Find levels by summing histogram to objective
level1= scipy.optimize.bisect(objective, H.min(), H.max(), args=(target1,))
level2= scipy.optimize.bisect(objective, H.min(), H.max(), args=(target2,))
level3= scipy.optimize.bisect(objective, H.min(), H.max(), args=(target3,))
# For nice contour shading with seaborn, define top level
level4=H.max()
levels=[level1,level2,level3,level4]
# Pass levels to normed kde plot
fig,ax=plt.subplots()
sns.kdeplot(x,y, shade=True,ax=ax,n_levels=levels,cmap="Reds_d",normed=True)
ax.set_aspect('equal')
plt.show()
结果图现在如下:
级别比我预期的略宽,但我认为这是正确的。
【问题讨论】:
-
我认为
n_levels只是将最小/最大值之间的范围划分为n等大小的步骤。 -
看来您应该能够删除
n_levels并传入levels=[X,Y,Z](因为级别只会传给plt.contourf)。但我不确定 X、Y、Z 水平应该是多少,因为等高线图的值不会等于您的百分比置信水平。 -
@David 我认为你应该澄清你的问题。它是关于“在 seaborn kdeplot 中设置置信水平”,现在我意识到我的回答并没有添加它,但我无法弄清楚这可能意味着什么。您要为哪个参数计算置信区间?它与非参数估计的 kde 有什么关系?
-
我刚刚发现了这个,因为我想做类似的事情。这段代码真正在做的是将等高线设置为直方图生成的经验密度函数的百分位数。我不是统计向导,但我认为这与通常意义上的置信区间不太一样。还值得指出的是,此代码仅在 2d 直方图箱都是相同区域时才有效(这是
np.histogram2d默认情况下所做的)。
标签: python matplotlib seaborn