如何结合散点图与密度热力图?实现点按聚类密度冷暖着色
实现基于局部密度的散点图颜色映射
你的需求完全可以实现,核心是通过计算每个点的局部密度,将密度值与蓝红渐变的色阶绑定,高密度点显红色(暖色),低密度点显蓝色(冷色)。
具体实现步骤
1. 计算每个点的局部密度
这里提供两种实用方法,任选其一即可:
方法一:k近邻距离法(直观高效)
通过计算每个点到最近k个邻居的平均距离,距离越小则密度越高,取距离倒数作为密度值:
import plotly.express as px import numpy as np from sklearn.neighbors import NearestNeighbors # 提取x、y列数据 X = data[['A', 'B']].values # 初始化近邻模型,k值可根据数据调整(比如k=5) nbrs = NearestNeighbors(n_neighbors=5).fit(X) # 计算每个点到k个邻居的距离 distances, _ = nbrs.kneighbors(X) # 计算密度值:平均距离的倒数,值越大密度越高 data['density'] = 1 / np.mean(distances, axis=1)
方法二:核密度估计法(平滑度更高)
用高斯核函数估计每个点的密度,适合需要更平滑密度分布的场景:
import plotly.express as px import numpy as np from sklearn.neighbors import KernelDensity X = data[['A', 'B']].values # 拟合KDE模型,bandwidth(带宽)需根据数据调整 kde = KernelDensity(bandwidth=0.5, kernel='gaussian').fit(X) # 计算密度值(转换为原始密度,而非对数) data['density'] = np.exp(kde.score_samples(X))
2. 绘制带密度颜色的散点图
将计算出的density列作为颜色映射变量,使用蓝红反转色阶(RdBu_r)让高密度对应红色:
fig = px.scatter(data, x='A', y='B', color='density', color_continuous_scale='RdBu_r', # 蓝→红的渐变(反转色阶) trendline='ols', # 保留原有的ols趋势线 color_continuous_midpoint=np.mean(data['density'])) # 可选:设置色阶中点 # 自定义颜色条标题 fig.update_layout(coloraxis_colorbar=dict(title='局部密度')) fig.show()
调整技巧
- 参数优化:k近邻的
k值、KDE的bandwidth需根据你的数据分布调整,建议多试几个值找到最佳效果 - 色阶自定义:如果默认的
RdBu_r不符合需求,可自定义色阶,比如color_continuous_scale=['#0066FF', '#FF3333'] - 性能优化:数据量较大时,优先用k近邻法,计算速度比KDE更快

内容的提问来源于stack exchange,提问作者Bob McBobson
相关产品推荐
相关产品推荐

