Python 从海生Kdeplot中提取特征参数

Python 从海生Kdeplot中提取特征参数,python,pandas,statistics,seaborn,kernel-density,Python,Pandas,Statistics,Seaborn,Kernel Density,我希望能够从使用Python的Seaborn生成的内核密度图中提取特征参数。虽然获得分布的中值有一个非常好的方法,但我想看看这是否可以推广到一维数据的多峰分布,尤其是二维情况 下面是一个最小的示例,我从中手动推导出1D情况下每个峰值的值。我希望利用现有的对象,找到更系统、更适用于2D的东西 import numpy as np import scipy import pandas as pd import seaborn as sns sns.set(style="white", color_c

我希望能够从使用Python的Seaborn生成的内核密度图中提取特征参数。虽然获得分布的中值有一个非常好的方法,但我想看看这是否可以推广到一维数据的多峰分布,尤其是二维情况

下面是一个最小的示例,我从中手动推导出1D情况下每个峰值的值。我希望利用现有的对象,找到更系统、更适用于2D的东西

import numpy as np
import scipy
import pandas as pd
import seaborn as sns
sns.set(style="white", color_codes=True, font_scale=2)

x1 = np.random.normal(-1.5,1,1000)
y1 = np.random.normal(1.5,1,1000)
x2 = np.random.normal(1.5,1,1000)
y2 = np.random.normal(-1.5,1,1000)
x = np.concatenate((x1,x2))
y = np.concatenate((y1,y2))
d = {'x': pd.Series(x), 'y': pd.Series(y)}
data = pd.DataFrame(d)

px = sns.kdeplot(data.x, shade=True)
x,y = px.get_lines()[0].get_data()
xysel = np.array([(x,y) for x,y in zip(x,y) if x < 0])
imax = np.argmax(xysel[:,1])
x_median = xysel[imax,0]
y_median = xysel[imax,1]
plt.vlines(x_median, 0, y_median, linestyles='dashed', color='b')
px.set_xlim(-5,5)
plt.show()

py = sns.kdeplot(data.y, shade=True, color='r')
x,y = py.get_lines()[0].get_data()
xysel = np.array([(x,y) for x,y in zip(x,y) if x > 0])
imax = np.argmax(xysel[:,1])
x_median = xysel[imax,0]
y_median = xysel[imax,1]
plt.vlines(x_median, 0, y_median, linestyles='dashed', color='r')
py.set_xlim(-5,5)
plt.show()

p = sns.kdeplot(data.x, data.y, shade=True)
将numpy导入为np
进口西皮
作为pd进口熊猫
导入seaborn作为sns
sns.set(style=“白色”,颜色代码=True,字体比例=2)
x1=np.随机正常(-1.5,11000)
y1=np.随机.正常(1.5,11000)
x2=np.随机.正常(1.5,11000)
y2=np.随机正常(-1.5,11000)
x=np.连接((x1,x2))
y=np.连接((y1,y2))
d={'x':pd.Series(x),'y':pd.Series(y)}
数据=pd.数据帧(d)
px=sns.kdeplot(data.x,shade=True)
x、 y=px.get_lines()[0]。get_data()
xysel=np.array([(x,y)表示x,如果x<0,则在zip(x,y)中为y])
imax=np.argmax(xysel[:,1])
x_中值=xysel[imax,0]
y_中值=xysel[imax,1]
plt.v线(x_中间线,0,y_中间线,线型为虚线,颜色为b)
px.set_xlim(-5,5)
plt.show()
py=sns.kdeplot(data.y,shade=True,color='r'))
x、 y=py.get_line()[0]。get_data()
xysel=np.array([(x,y)表示x,如果x>0,则zip中的y(x,y)])
imax=np.argmax(xysel[:,1])
x_中值=xysel[imax,0]
y_中值=xysel[imax,1]
plt.v线(x_中间线,0,y_中间线,线型为虚线,颜色为r)
py.set_xlim(-5,5)
plt.show()
p=sns.kdeplot(data.x,data.y,shade=True)

您可以通过以下代码获得路径:

ax = sns.kdeplot(data.x, data.y, shade=True)

for path in ax.collections[-1].get_paths():
    x, y = path.vertices.mean(axis=0)
    ax.plot(x, y, "ro")
以下是输出:

ax.collections
是与Axes对象中的每个级别相对应的
PathCollection
对象的列表

每个
PathCollection
都包含一个
Path
对象列表,您可以通过
get\u paths()
方法获取该对象

路径的点保存在
顶点
数组中

如果要获取更多信息,需要获取轴的返回对象。contourf
,首先修补
contourf()
方法:

from matplotlib.axes import Axes

def contourf(self, *args, **kw):
    self._quadcontourset = self.old_contourf(*args, **kw)
    return self._quadcontourset

Axes.old_contourf = Axes.contourf
Axes.contourf = contourf

然后您可以通过
ax.\u quadcouroset
获得
quadcouroset
对象。请阅读
QuadContourSet
的源代码以了解如何使用它。

我鼓励您直接使用statsmodels KDE对象。这将比试图从等高线图中获取信息更直接、更强大。