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

Seaborn重叠直方图未按预期显示问题求助

解决Seaborn histplot双直方图无法正常重叠的问题

问题说明

使用Seaborn的histplot绘制两个直方图:

  • 蓝色直方图对应完整数据集total_means
  • 红色直方图对应total_means中处于68%置信区间内的子集
    但最终两个直方图未按预期重叠,呈现错位状态。

原代码如下:

import numpy as np
from scipy.stats import norm
import seaborn as sns
import matplotlib.pyplot as plt

data = np.sin(np.arange(0, 6*np.pi, 0.1)) * 100
sns.scatterplot(x=[np.mean(data)], y=[0])
sns.lineplot(data)

population_size = 10000
sample_size = 100
total_means = []
for x in range(population_size):
    total_means.append(np.mean(np.random.choice(data, 100)))

total_means = np.array(total_means)
sns.histplot(total_means, kde=True)

# 计算68%置信区间
from scipy.stats import norm
z1 = norm.ppf(.50 - .68/2)
se = np.array(data).std() / sample_size ** .5
x1 = z1 * se + np.array(data).mean()
z2 = norm.ppf(.50 + .68/2)
x2 = z2 * se + np.array(data).mean()
print(x1, x2)

plt.xticks(np.arange(total_means.min(), total_means.max(), 10))
plt.xticks(np.arange(0, 500, 100))
sns.histplot(total_means, kde=True)
sns.histplot(total_means[(total_means >= x1) & (total_means <= x2)], kde=True, color='r')

原结果特征:蓝色与红色直方图错位,红色直方图未覆盖蓝色直方图的中间区域,坐标轴刻度显示异常。

问题根源

  1. 重复绘制完整数据集直方图:代码中先后两次调用sns.histplot(total_means, kde=True),导致图层混乱
  2. 坐标轴刻度被强制覆盖:plt.xticks(np.arange(0, 500, 100))将刻度强制设为0-500,但total_means均值接近0,导致直方图显示错位
  3. 子集直方图未对齐分箱:未指定bins参数时,Seaborn会自动计算不同分箱,导致两个直方图无法重叠

修复方案

  • 删除重复的完整数据集直方图绘制代码
  • 基于total_means实际范围设置坐标轴刻度
  • 手动指定bins参数,确保两个直方图分箱一致
  • 添加alpha参数设置透明度,便于观察重叠效果

修正后完整代码

import numpy as np
from scipy.stats import norm
import seaborn as sns
import matplotlib.pyplot as plt

# 生成原始数据
data = np.sin(np.arange(0, 6*np.pi, 0.1)) * 100

# 单独展示原始数据图,避免与直方图混叠
sns.scatterplot(x=[np.mean(data)], y=[0])
sns.lineplot(data)
plt.show()

# 生成样本均值数据集
population_size = 10000
sample_size = 100
total_means = []
for _ in range(population_size):
    total_means.append(np.mean(np.random.choice(data, sample_size)))
total_means = np.array(total_means)

# 计算68%置信区间
z1 = norm.ppf(.50 - .68/2)
z2 = norm.ppf(.50 + .68/2)
se = data.std() / np.sqrt(sample_size)
x1 = z1 * se + data.mean()
x2 = z2 * se + data.mean()
print(f"68%置信区间:[{x1:.2f}, {x2:.2f}]")

# 绘制对齐的直方图
bins = np.arange(total_means.min(), total_means.max(), 2)
plt.figure(figsize=(10,6))
sns.histplot(total_means, kde=True, bins=bins, label='全部样本均值')
sns.histplot(total_means[(total_means >= x1) & (total_means <= x2)], 
             kde=True, bins=bins, color='r', alpha=0.5, label='68%置信区间内样本均值')

# 设置可视化细节
plt.xticks(np.arange(total_means.min(), total_means.max(), 5))
plt.legend()
plt.xlabel('样本均值')
plt.ylabel('频数')
plt.title('样本均值分布与68%置信区间子集')
plt.show()

效果说明

修正后,红色直方图会准确覆盖在蓝色直方图的中间68%区域,透明度设置可清晰展示重叠部分,坐标轴刻度也匹配数据实际范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:07:22