Seaborn histplot不同数据范围下直方图计数不一致问题
问题描述
我用Seaborn绘制直方图时遇到了计数不一致的问题:
- 第一次绘制
kms_driven<=100000的直方图:
sns.histplot(df.query('kms_driven<=100000'),x='kms_driven',binwidth=10000) plt.show()
该图中0-10000区间有851个数据点,10000-20000区间有1266个数据点。
- 第二次绘制
kms_driven<=200000的直方图:
sns.histplot(df.query('kms_driven<=200000'),x='kms_driven',binwidth=10000) plt.show()
此时0-10000区间计数仍为851,但10000-20000区间计数变成了约900,和之前的1266不符。
我手动统计了kms_driven<=200000数据的各区间数量:
for i in range(0, 200000, 10000): a = i b = i + 10000 print(f'{a} - {b}:', df.query('kms_driven<=200000').query('(kms_driven <= @b) & (kms_driven > @a)').kms_driven.count())
统计结果显示10000-20000区间确实是1266,但两幅直方图的该区间计数不一致,请问原因是什么?
问题原因
这是因为Seaborn的histplot仅设置binwidth时,会根据当前数据集的整体范围自动调整区间起始位置,而非固定从0开始划分区间:
- 第一次绘图时,数据范围是0到100000,
binwidth=10000会生成从0开始的区间:[0,10000), [10000,20000), ..., [90000,100000],和手动统计的区间规则完全匹配,所以10000-20000区间计数为1266。 - 第二次绘图时,数据范围扩大到0到200000,Seaborn可能会调整区间起始点(比如从某个非0值开始),导致原本属于
[10000,20000)的部分数据被划分到相邻区间,最终显示的计数就变少了。
解决办法
如果要让两次绘图的区间划分完全一致,和手动统计规则匹配,可以手动指定区间边界,而非仅设置binwidth:
# 手动生成从0到200000、步长10000的区间边界 bins = range(0, 200001, 10000) # 第一次绘图 sns.histplot(df.query('kms_driven<=100000'), x='kms_driven', bins=bins) plt.show() # 第二次绘图 sns.histplot(df.query('kms_driven<=200000'), x='kms_driven', bins=bins) plt.show()
这样两次绘图的区间划分完全统一,就能得到和手动统计匹配的计数结果。
内容的提问来源于stack exchange,提问作者Анатолий Осипов
相关产品推荐
相关产品推荐

