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

如何为seaborn histplot多分布直方图的分箱概率设置权重

实现方案

不需要修改seaborn计算完成的分箱结果,直接利用histplot自带的weights参数即可实现需求。
stat='probability'模式下,分箱高度的计算逻辑是:箱内样本的权重总和 / 全量样本的权重总和。只要给同一分布的所有样本分配统一权重,让每个分布的总权重等于你预设的系数,最终所有分箱的概率总和自然为1,且每个分布的总概率占比恰好等于预设系数。

具体实现代码

注意原示例代码缺少numpy导入,以下是可直接运行的完整代码:

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

rdata = pd.DataFrame()
np.random.seed(2022)
rdata['Recession'] = skewnorm.rvs(1, loc=3000, scale=400, size=100000)
rdata['Recovery'] = skewnorm.rvs(0, loc=3300, scale=300, size=100000)
rdata['Expansion'] = skewnorm.rvs(-1, loc=3800, scale=200, size=100000)
rdata['Slowdown'] = skewnorm.rvs(-3, loc=3600, scale=250, size=100000)

# 定义每个分布的目标总概率占比
weight_config = {
    'Recession': 0.4,
    'Recovery': 0.2,
    'Expansion': 0.2,
    'Slowdown': 0.2
}

# 宽表转长表,方便给每个样本匹配权重
long_df = rdata.melt(var_name='economic_cycle', value_name='indicator')
# 单个样本权重 = 对应分布的目标总占比 / 该分布的样本总数
long_df['sample_weight'] = long_df['economic_cycle'].map(weight_config) / long_df.groupby('economic_cycle')['indicator'].transform('count')

sns.histplot(
    data=long_df,
    x='indicator',
    hue='economic_cycle',
    bins=50,
    stat='probability',
    weights='sample_weight',
    cumulative=False,
    kde=True
)
plt.show()

效果说明

  • 运行代码后,四个分布所有分箱的概率总和恰好为1
  • Recession的全部分箱概率和为0.4,其余三个分布的分箱概率和各为0.2,完全符合加权要求
  • 附带的kde曲线会自动适配样本权重,不需要额外调整

不推荐的备选方案

如果一定要在seaborn计算完分箱概率后再乘以系数,可以在绘图后遍历Axes对象的patches属性(对应每个分箱的矩形元素),识别每个矩形所属的分布后乘以对应系数,但该方法需要自行匹配分布和矩形的对应关系,且无法同步调整kde曲线,实用性很低。

多分布直方图效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:02:16