获取seaborn中核密度估计的绘图点
我正在使用这段代码
kde = sns.kdeplot(x = data, fill = True, color = "black", alpha = 0.1)
来获取我数据的核密度估计(kde),效果很好。现在我想获取绘制图表时用到的所有 x 和 y 点,我正在这样做:
poly = kde.collections[0]
x_values = poly.get_paths()[0].vertices[:, 0]
y_values = poly.get_paths()[0].vertices[:, 1]
但是,x 值却是先增加然后又减少。这是为什么呢?我明白 y 值应该是先增加后减少,但我原本以为 x 值应该是一直增加的,因为曲线是从左到右绘制的。顺便说一下,这些点的值是合理的,并且与图表相符,除了这个行为。
1 个回答
2
使用 fill=True
时,会创建一个填充的多边形。可以用 ax.text()
来显示每个圆周点的索引。看起来首先是这些点形成了多边形的底部,然后再沿着多边形的上部分返回。
下面的代码展示了每十个点的顺序,并使用 ax
,因为 kde
这个名字可能会让人对子图感到困惑。
import seaborn as sns
import numpy as np
ax = sns.kdeplot(x=np.random.randn(200).cumsum(), fill=True, color="black", alpha=0.1)
poly = ax.collections[0]
x_values = poly.get_paths()[0].vertices[:, 0]
y_values = poly.get_paths()[0].vertices[:, 1]
for i, (x, y) in enumerate(zip(x_values[::10], y_values[::10])):
ax.text(x, y, i, ha='center', va='center', color='b')
如果只想得到曲线的点,可以用 kdeplot
创建时设置 fill=False
。
import seaborn as sns
import numpy as np
data = np.random.randn(200).cumsum()
ax = sns.kdeplot(x=data, fill=True, color="black", alpha=0.1)
sns.kdeplot(x=data, fill=False, color="red", ax=ax) # temporarily draw a curve
x_values, y_values = ax.lines[0].get_data() # get the coordinates of the curve
ax.lines[0].remove() # remove the curve again
for i, (x, y) in enumerate(zip(x_values[::10], y_values[::10])):
ax.text(x, y, i, ha='center', va='center', color='b')
使用曲线而不是多边形会更安全,因为未来的版本中它们的方向和起始点可能会不同。多边形的第一个点可能就是曲线的第一个点(为了“闭合”多边形)。曲线从来不会完全为零。你可以使用 cut=
参数将曲线延伸到几乎为零的区域。请注意,kde只是pdf的一个近似值。它的准确性取决于底层分布在局部看起来有多像高斯分布。