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

如何在百分比直方图(非原始数据)上绘制拟合曲线

绘制贴合分箱百分比的拟合曲线

你遇到的问题核心是:seaborn的kde=True是对原始数据集做核密度估计(KDE),而非针对分箱后的百分比数据,所以会出现不符合分箱趋势的额外凸起。要实现贴合分箱百分比的拟合曲线,需要先提取直方图的分箱统计数据,再针对这些数据做拟合。

步骤1:绘制百分比直方图并提取分箱信息

先复用你原有的直方图代码,同时获取直方图返回的分箱边界、每个分箱的百分比等关键数据:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter

# 替换为你的实际数据集
np.random.seed(42)
data = np.random.normal(loc=50, scale=15, size=1000)

# 绘制百分比直方图,同时捕获分箱统计结果
bin_percentages, bin_edges, _ = plt.hist(
    data,
    weights=np.ones(len(data)) / len(data),
    bins=5
)
plt.gca().yaxis.set_major_formatter(PercentFormatter(1))
plt.grid()

# 计算每个分箱的中点(用于拟合的x值)
bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2

步骤2:拟合贴合分箱的曲线

根据需求可以选择两种拟合方式:

方式1:多项式拟合(严格贴合分箱趋势)

适合需要曲线完全匹配分箱百分比变化趋势的场景,这里以二次多项式为例(可根据数据调整阶数):

from scipy.optimize import curve_fit

# 定义拟合函数(示例为二次多项式,可修改为更高阶或其他形式)
def polynomial_fit(x, a, b, c):
    return a * x**2 + b * x + c

# 拟合分箱中点与对应百分比
fit_params, _ = curve_fit(polynomial_fit, bin_centers, bin_percentages)

# 生成平滑的拟合曲线x轴数据
x_fit = np.linspace(bin_edges[0], bin_edges[-1], 100)
# 计算拟合曲线的y值(百分比)
y_fit = polynomial_fit(x_fit, *fit_params)

# 绘制拟合曲线
plt.plot(x_fit, y_fit, 'r-', linewidth=2, label='多项式拟合曲线')
plt.legend()
plt.show()

方式2:加权核密度估计(平滑贴合分箱分布)

如果想要更平滑的曲线,同时保留分箱的分布特征,可以基于分箱中点和百分比做加权KDE:

from scipy.stats import gaussian_kde

# 创建加权KDE,权重为每个分箱的百分比
kde = gaussian_kde(bin_centers, weights=bin_percentages)

# 生成拟合曲线的x轴数据
x_fit = np.linspace(bin_edges[0], bin_edges[-1], 100)
# 计算拟合曲线的y值(已归一化到百分比范围)
y_fit = kde(x_fit)

# 绘制拟合曲线
plt.plot(x_fit, y_fit, 'g-', linewidth=2, label='加权KDE拟合曲线')
plt.legend()
plt.show()

关键说明

  • 两种方法都是基于分箱后的百分比数据做拟合,不会出现原始数据KDE的额外凸起
  • 多项式拟合的阶数可根据分箱的分布趋势调整(比如线性、三次多项式)
  • 加权KDE的平滑程度可通过gaussian_kde的bw_method参数调整(比如bw_method=0.5缩小带宽,曲线更贴合分箱)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:10:15