You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Python代码使散点簇与核密度概率等高线匹配?

解决核密度图与散点簇不匹配的问题

你的问题核心是phi2是环形变量(取值范围-180°~180°,对应圆周),但默认的高斯KDE是为线性变量设计的,没有考虑环形空间的连续性——-180°和180°在环形空间里是相邻的,但线性KDE会把它们当成距离360°的远隔点,导致原本的两个环形簇被合并成一个峰值,和散点的三个簇不匹配。

以下是修改方案:

1. 适配环形变量的核密度估计

通过复制环形数据并平移,让KDE识别到-180°和180°的连续性;同时调整带宽让峰值更贴合数据簇。

2. 修改后的完整代码

import numpy as np
from scipy.stats import circvar, circmean
import scipy.stats as st
import matplotlib.pyplot as plt

# 原始数据
phi2 = np.array([  73.62324995,  122.64334345,   72.67064757, -175.63713227,
                  -176.42631705,  111.97090782,  112.43262405,  113.1094183 ,
                   111.53501099,  110.69594668,  -75.46326239,  -67.76160179,
                   -95.94455459,  -64.01216275,  -93.67976318,   12.22483834,
                    11.24380368,    7.12787335,    8.57004673,    9.57479941])

theta = np.array([161.96978904, 174.70995924, 159.42606079, 174.98472276,
                  174.94378114, 167.49406671, 167.38426198, 164.57103987,
                  164.51372335, 164.46138757,  22.65628947,  13.59729108,
                   27.54987277,  16.46934502,  28.45572831,   4.02895771,
                    3.79725376,   3.9735054 ,   3.62785328,   3.48080227])

N = len(phi2)

# -------------------------- 适配环形变量的KDE --------------------------
# 复制phi2的环形数据:将原phi2加360,模拟环形连续性
values = np.vstack([phi2, theta])
values_ring = np.hstack([values, np.array([values[0] + 360, values[1]])])

# 创建KDE,手动设置带宽(bw_method越小,峰值越尖锐,越贴合簇)
kernel = st.gaussian_kde(values_ring, bw_method=0.2)

# 生成包含环形扩展的网格:-180~540(覆盖原区间+平移后的区间)
xx_full, yy_full = np.mgrid[-180:540:((N+2)*1j), 0:180:((N+2)*1j)]
positions_full = np.vstack([xx_full.ravel(), yy_full.ravel()])
f_full = np.reshape(kernel(positions_full).T, xx_full.shape)

# 将平移后的区间(180~540)映射回原区间(-180~180),合并密度值
f = f_full[:(N+2), :] + f_full[(N+2):, :]
xx = xx_full[:(N+2), :]  # 取原区间的x网格

# -------------------------- 绘图 --------------------------
fig, ax = plt.subplots(figsize=(8,6))

# 等高线图
levels = np.linspace(f.min(), f.max(), 20)
cfset = ax.contourf(xx, yy_full, f, levels=levels, cmap='viridis', zorder=0)
plt.colorbar(cfset, ax=ax, label='Kernel Density')

# 散点图
scatter = ax.scatter(phi2, theta, color="red", linewidth=1, edgecolor="black", s=60, marker='x')

ax.set_xlim([-180, 180])                                                                           
ax.set_ylim([0, 180])
ax.set_xlabel('phi2 (°)')
ax.set_ylabel('theta (°)')
plt.show()

关键修改说明

  • 环形数据处理:将phi2数据复制并平移360°,让KDE识别到-180°和180°的连续性,避免环形簇被合并。
  • 带宽调整:通过bw_method=0.2缩小带宽,让KDE的峰值更尖锐,精准匹配散点的三个簇(可根据实际效果调整该值,越大越平滑,越小越尖锐)。
  • 网格扩展与合并:生成覆盖原区间和平移后区间的网格,计算密度后将平移部分映射回原区间,得到正确的环形密度分布。

内容的提问来源于stack exchange,提问作者Laz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:18:18