如何在Python Matplotlib直方图的分箱内标注对应观测的年份信息
带分箱年份标注的指数收益直方图实现方案
核心实现逻辑
Matplotlib原生plt.hist仅会按分箱累计计数绘制整体柱形,没有内置的分箱内逐观测标注功能。我们可以手动完成两个关键步骤实现目标:
- 匹配每一个原始收益值对应的所属分箱区间
- 按每个分箱内的观测出现顺序,逐次沿纵轴堆叠位置标注对应年份
整个实现不需要额外安装第三方依赖,完全基于原有Matplotlib生态完成
完整可运行代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 原始输入数据 returns = (0.08,0.05,-0.15,0.12,-0.18,0.02,0.25) years = (2010,2011,2012,2013,2014,2015,2016) data = pd.DataFrame(returns, columns = ["Return"], index = years) bins = [-0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5] # 初始化画布,绘制基础直方图 fig, ax = plt.subplots(figsize=(8,5)) ax.hist( data["Return"], bins=bins, edgecolor="white", alpha=0.3 # 降低柱体透明度,避免遮挡标注 ) # 预定义分箱中心位置、分箱累计计数器 bin_centers = [(bins[i] + bins[i+1])/2 for i in range(len(bins)-1)] bin_counts = {i: 0 for i in range(len(bins)-1)} # 逐观测匹配分箱、放置年份标注 for ret, year in zip(returns, years): # 计算当前收益所属的分箱索引 bin_idx = np.digitize(ret, bins) - 1 # 跳过不在分箱范围内的异常值 if bin_idx < 0 or bin_idx >= len(bin_centers): continue # 确定当前标注的纵轴位置(对应分箱内的第n个观测) y_pos = bin_counts[bin_idx] # 在分箱中心位置放置居中对齐的年份标注 ax.text( x=bin_centers[bin_idx], y=y_pos + 0.4, # 偏移量让文字落在单格计数的视觉中心 s=str(year), ha="center", fontsize=10 ) # 更新该分箱的累计计数 bin_counts[bin_idx] += 1 # 调整坐标轴配置 ax.set_xlabel("指数收益率") ax.set_ylabel("观测计数") ax.set_xticks(bins) ax.set_ylim(0, max(bin_counts.values()) + 0.5) plt.tight_layout() plt.show()
效果匹配说明
- -20%~-10%收益分箱内,2012年(-15%)、2014年(-18%)两个观测,会分别在y=0、y=1的堆叠高度位置被居中标注,可直接识别对应年份
- 标注位置全部对齐在所属分箱的x轴中心,不会出现文字偏移出柱体的问题
- 柱体设置半透明效果,既保留直方图的分箱分布轮廓,又不会遮挡堆叠位置的年份文字
内容的提问来源于stack exchange,提问作者Kyle_Stockton
相关产品推荐
相关产品推荐

