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

如何用第三个变量加权实现Matplotlib/Seaborn的加权KDE散点图?

带权重的二维核密度图优化实现

问题背景

我有一组二维分布的点,使用sns.kdeplot可正常绘制密度图。但希望引入第三个变量,使该变量值较高的点在核密度估计时拥有更高权重。为展示预期效果,生成了如下数据集:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from scipy.stats import multivariate_normal

data_points = multivariate_normal([0.0, 0.0], [[9, 3], [3,3]]).rvs(250)
df = pd.DataFrame(data=data_points, columns=['x', 'y'])
df['intensity'] = round(np.sqrt(df['x']**2 + df['y']**2))

目前通过重复intensity变量对应行数的方式模拟权重效果:

df_repeat = df.loc[df.index.repeat(df['intensity'])]

对比绘图代码:

fig, ax = plt.subplots(1,2)
sns.kdeplot(ax = ax[0], data =df,  x = 'x',y = 'y')
sns.kdeplot(ax = ax[1], data =df_repeat,  x = 'x',y = 'y')

这种方式能达到预期效果,但存在数据冗余、效率较低的问题,有没有更简洁的实现方法?

优化方案

直接使用seaborn.kdeplot内置的weights参数即可,无需通过重复行模拟权重。该参数可直接传入每个样本对应的权重值,核密度估计过程会自动根据权重分配样本的贡献度,效果和重复行完全一致,但更高效简洁。

优化后的完整代码:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from scipy.stats import multivariate_normal

# 生成数据集
data_points = multivariate_normal([0.0, 0.0], [[9, 3], [3,3]]).rvs(250)
df = pd.DataFrame(data=data_points, columns=['x', 'y'])
df['intensity'] = round(np.sqrt(df['x']**2 + df['y']**2))

# 绘制对比图
fig, ax = plt.subplots(1, 2, figsize=(12, 5))

# 无权重的原始密度图
sns.kdeplot(ax=ax[0], data=df, x='x', y='y', fill=True)
ax[0].set_title('无权重核密度图')

# 带权重的密度图
sns.kdeplot(ax=ax[1], data=df, x='x', y='y', weights=df['intensity'], fill=True)
ax[1].set_title('带intensity权重的核密度图')

plt.tight_layout()
plt.show()

方案优势

  • 内存高效:无需创建冗余的重复行数据集,避免权重值较大时的数据膨胀
  • 代码简洁:直接通过参数声明权重逻辑,可读性更强
  • 计算高效:减少了数据复制的开销,核密度估计过程更快速

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:58:23