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

Seaborn kdeplot与直方图拟合偏差问题求助(数值差10倍)

Seaborn kdeplot与直方图数值差异过大的解决方法

问题描述

使用Seaborn绘制加权KDE曲线时,蓝色KDE曲线数值比橙色直方图大10倍,导致可视化结果失真。代码如下:

import seaborn as sns 
import matplotlib.pyplot as plt 
import numpy as np

BH = np.array([141.19618068420274, 191.2406412961248, 346.01168490938585, 230.14257295050672, 185.01589850153252, 245.67488131757796, 175.6108949133985, 325.03739349020094, 379.41413332517686, 105.59295515652147 ])

MT = np.array([0.015004641668689452, 0.011144290004860507, 0.007974195145875648, 0.019437031417186952, 0.0036642005992589023, 0.0036642005992589023, 0.0036642005992589023,0.0036642005992589023, 0.0023554322266426775,0.0023554322266426775 ])

sns.kdeplot(x=BH, weights=MT, bw_adjust=0.2, log_scale=True, common_grid=True, bw_method='silverman')
plt.hist(BH, weights=MT, bins=np.logspace(2, 7.5, num=50), log=True, histtype='step', density=True)
plt.show()

问题原因

  • sns.kdeplot设置log_scale=True时,在原始数据空间计算概率密度,再将x轴转为对数刻度;
  • plt.hist使用对数间距bins并设置density=True时,计算的是对数数据空间的概率密度;
  • 两者密度值存在转换关系:对数空间密度 = 原始值 × 原始空间密度,因此出现10倍左右的数值差异。

解决方法

方法一:在对数空间计算KDE(推荐)

先对原始数据取对数,在对数空间计算KDE后,再将x轴转换为对数刻度(显示原始数值),与直方图的密度逻辑完全匹配:

import seaborn as sns 
import matplotlib.pyplot as plt 
import numpy as np

BH = np.array([141.19618068420274, 191.2406412961248, 346.01168490938585, 230.14257295050672, 185.01589850153252, 245.67488131757796, 175.6108949133985, 325.03739349020094, 379.41413332517686, 105.59295515652147 ])
MT = np.array([0.015004641668689452, 0.011144290004860507, 0.007974195145875648, 0.019437031417186952, 0.0036642005992589023, 0.0036642005992589023, 0.0036642005992589023,0.0036642005992589023, 0.0023554322266426775,0.0023554322266426775 ])

# 对BH取对数,在对数空间计算KDE
log_BH = np.log(BH)
sns.kdeplot(x=log_BH, weights=MT, bw_adjust=0.2, bw_method='silverman')
# 将x轴转为对数刻度,显示原始数值
plt.xscale('log')

# 保持原直方图参数,此时密度与KDE完全匹配
plt.hist(BH, weights=MT, bins=np.logspace(2, 7.5, num=50), log=True, histtype='step', density=True)
plt.show()

方法二:手动归一化直方图到原始空间密度

去掉直方图的density=True,手动计算原始空间的概率密度,与kdeplot的密度逻辑匹配:

import seaborn as sns 
import matplotlib.pyplot as plt 
import numpy as np

BH = np.array([141.19618068420274, 191.2406412961248, 346.01168490938585, 230.14257295050672, 185.01589850153252, 245.67488131757796, 175.6108949133985, 325.03739349020094, 379.41413332517686, 105.59295515652147 ])
MT = np.array([0.015004641668689452, 0.011144290004860507, 0.007974195145875648, 0.019437031417186952, 0.0036642005992589023, 0.0036642005992589023, 0.0036642005992589023,0.0036642005992589023, 0.0023554322266426775,0.0023554322266426775 ])

# 绘制原始空间密度的KDE
sns.kdeplot(x=BH, weights=MT, bw_adjust=0.2, log_scale=True, common_grid=True, bw_method='silverman')

# 手动计算原始空间的直方图密度
total_weight = MT.sum()
bins = np.logspace(2, 7.5, num=50)
bin_widths = np.diff(bins)
# 计算每个bin的权重和
bin_weights, _ = np.histogram(BH, weights=MT, bins=bins)
# 原始空间密度 = bin权重和 / (总权重 × bin宽度)
density = bin_weights / (total_weight * bin_widths)

# 绘制直方图
plt.step(bins[:-1], density, where='post', color='orange', linestyle='--')
plt.yscale('log')
plt.show()

内容的提问来源于stack exchange,提问作者Matías Liempi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:30:52