我尝试使用Seaborn在极投影上绘制一个二元(联合)KDE。Seaborn不支持这个,Scipy也不直接支持角(von Mises)KDE。
scipy gaussian_kde and circular data解决了一个相关但不同的情况。相似之处是-随机变量被定义在单位圆上线性间隔的Angular 上;绘制KDE。差异:我想用Seaborn的joint kernel density estimate support来绘制这样的等高线图-
但没有分类(“物种”)变异,并在极投影上。边缘图将是很好的拥有,但并不重要。
我的情况的直线版本将是
import matplotlib
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
import seaborn as sns
from numpy.random._generator import default_rng
angle = np.repeat(
np.deg2rad(
np.arange(0, 360, 10)
),
100,
)
rand = default_rng(seed=0)
data = pd.Series(
rand.normal(loc=50, scale=10, size=angle.size),
index=pd.Index(angle, name='angle'),
name='power',
)
matplotlib.use(backend='TkAgg')
joint = sns.JointGrid(
data.reset_index(),
x='angle', y='power'
)
joint.plot_joint(sns.kdeplot, bw_adjust=0.7, linewidths=1)
plt.show()
但是这是以错误的投影示出的,并且在0 °和360 °的Angular 之间也不应该有递减的轮廓线。
当然,正如Creating a circular density plot using matplotlib and seaborn所解释的,在极坐标投影中使用现有高斯KDE的简单方法是无效的,即使我想这样做也不行,因为axisgrid.py
对子图设置进行了硬编码,没有任何参数:
f = plt.figure(figsize=(height, height))
gs = plt.GridSpec(ratio + 1, ratio + 1)
ax_joint = f.add_subplot(gs[1:, :-1])
ax_marg_x = f.add_subplot(gs[0, :-1], sharex=ax_joint)
ax_marg_y = f.add_subplot(gs[1:, -1], sharey=ax_joint)
我从一个monkeypatching方法开始:
import scipy.stats._kde
import numpy as np
def von_mises_estimate(
points: np.ndarray,
values: np.ndarray,
xi: np.ndarray,
cho_cov: np.ndarray,
dtype: np.dtype,
real: int = 0
) -> np.ndarray:
"""
Mimics the signature of gaussian_kernel_estimate
https://github.com/scipy/scipy/blob/main/scipy/stats/_stats.pyx#L740
"""
# https://stackoverflow.com/a/44783738
# Will make this a parameter
kappa = 20
# I am unclear on how 'values' would be used here
class VonMisesKDE(scipy.stats._kde.gaussian_kde):
def __call__(self, points: np.ndarray) -> np.ndarray:
points = np.atleast_2d(points)
result = von_mises_estimate(
self.dataset.T,
self.weights[:, None],
points.T,
self.inv_cov,
points.dtype,
)
return result[:, 0]
import seaborn._statistics
seaborn._statistics.gaussian_kde = VonMisesKDE
这个函数成功地代替了默认的高斯函数,但是(1)它是不完整的,(2)我不清楚是否有可能说服联合绘图方法使用新的投影。
通过Gimp变换,这是一个非常扭曲和低质量的预览:
尽管径向轴线将从中心向外增加而不是减小。
2条答案
按热度按时间c9x0cxw01#
下面是一个方法的想法:
sin
和cos
将极坐标转换为笛卡尔坐标jointplot
(或kdeplot
,这可以包括hue
)PS:这是一个填充的版本可能看起来像(与
cmap='turbo'
):如果希望顶部为0,并让Angular 顺时针旋转,则需要在调用2D
kdeplot
时切换x=
和y=
。x759pob22#
我过去使用
seaborn
和matplotlib
的极投影的组合来完成这个任务。下面是一个例子:希望你能在那里适应你的需要?