如何基于区间数据绘制百分位数图?解决df.hist()分箱异常问题
解决基于区间频率数据绘制百分位数图的问题
原代码存在两个核心问题:
df.hist()是为原始观测数据设计的直方图绘制方法,完全不适用于已经汇总好的区间-频率统计数据- 原代码中
cumulativePercent的计算逻辑错误,当前算出的是单个区间的占比,而非累积百分位数
修正后的完整代码
import pandas as pd import matplotlib.pyplot as plt # 初始化区间与频率数据 idx = pd.IntervalIndex.from_breaks([39.9, 42.9, 45.9, 48.9, 51.9, 54.9, 57.9]) df = pd.DataFrame({"Bin": idx, "Frequency": [2, 2, 5, 5, 12, 3]}) # 计算累积频率与正确的累积百分位数 n = df["Frequency"].sum() df['cumulativeSumFreq'] = df["Frequency"].cumsum() df['cumulativePercent'] = (df['cumulativeSumFreq'] / n) * 100 # 基于累积频率计算占比 # 提取区间中点作为x轴标识(也可根据需求改用左/右边界) df['bin_mid'] = df['Bin'].apply(lambda x: (x.left + x.right) / 2) # 绘制累积百分位数折线图 plt.figure(figsize=(8, 5)) plt.plot(df['bin_mid'], df['cumulativePercent'], marker='o', linestyle='-', color='#2c3e50') # 可选:叠加条形图展示区间累积贡献 plt.bar(df['bin_mid'], df['cumulativePercent'], width=2.8, alpha=0.3, color='#3498db') # 设置图表样式 plt.xlabel('区间中点') plt.ylabel('累积百分位数 (%)') plt.title('百分位数累积分布图') plt.xticks(df['bin_mid']) plt.grid(axis='y', linestyle='--', alpha=0.7) plt.show()
关键说明
- 弃用
df.hist():你的数据是汇总后的统计结果,不是原始单条观测值,hist方法的应用场景完全不匹配 - 修正累积占比计算:必须基于
cumulativeSumFreq才能得到正确的累积百分位数,原代码的计算逻辑仅能得到单个区间的占比 - 选择合适的x轴数据:用区间中点能更准确代表整个区间的位置,也可根据需求替换为区间左/右边界
- 图表类型选择:折线图最适合展示累积百分位数的变化趋势,叠加条形图可直观呈现每个区间的累积贡献
若需绘制非累积的区间百分位数条形图
如果需求是展示单个区间的占比而非累积值,可使用以下代码:
plt.figure(figsize=(8, 5)) plt.bar(df['bin_mid'], (df['Frequency']/n)*100, width=2.8, color='#3498db') plt.xlabel('区间中点') plt.ylabel('区间百分位数 (%)') plt.title('区间百分位数分布图') plt.xticks(df['bin_mid']) plt.grid(axis='y', linestyle='--', alpha=0.7) plt.show()
内容的提问来源于stack exchange,提问作者Jimmy3421
相关产品推荐
相关产品推荐

