如何对uproot提取的ROOT TH2直方图重bin后用matplotlib/mplhep绘图
TH2重bin后对接mplhep绘图的实现方案
核心逻辑:uproot读取TH2调用to_numpy()返回值固定为(bin_count_array, (x_bin_edges, y_bin_edges))结构,只要重bin后保持该结构,即可直接传入mplhep.hist2dplot()绘图,无需调整原有绘图流程。
方法1:uproot内置重bin(最简便,推荐日常使用)
uproot 4.x及以上版本的to_numpy()方法原生支持x、y轴独立配置重bin因子,读取阶段直接完成重bin,无需手动处理数组:
import uproot import mplhep as hep import matplotlib.pyplot as plt # 打开ROOT文件 f = uproot.open("your_analysis_file.root") # 配置重bin因子:x轴每2个bin合并为1个,y轴每3个bin合并为1个 rebin_x_factor = 2 rebin_y_factor = 3 # 读取时直接完成重bin rebinned_h = f["path/to/your/TH2"].to_numpy( rebin=rebin_x_factor, rebin_y=rebin_y_factor ) # 绘图流程和原始直方图完全一致 fig, ax = plt.subplots(figsize=(8,6)) hep.hist2dplot(rebinned_h, ax=ax) plt.show()
该方法会自动校验原始bin数是否能被重bin因子整除,若不满足会直接抛出明确错误提示,避免手动处理数组时的维度错位问题。
方法2:纯numpy手动重bin(无额外依赖,支持自定义逻辑)
如果需要自定义重bin逻辑(比如非均匀合并、过滤特定bin等),可以通过数组重塑+求和的方式实现,只要按规则生成新的bin边界即可:
import numpy as np # 先读取原始直方图 orig_counts, (orig_xedges, orig_yedges) = f["path/to/your/TH2"].to_numpy() # 配置重bin因子 rebin_x = 2 rebin_y = 3 # 校验bin数可整除,避免边界错位 assert orig_counts.shape[1] % rebin_x == 0, "x轴bin数无法被重bin因子整除" assert orig_counts.shape[0] % rebin_y == 0, "y轴bin数无法被重bin因子整除" # 对bin计数重塑后按合并维度求和 rebinned_counts = orig_counts.reshape( orig_counts.shape[0]//rebin_y, rebin_y, orig_counts.shape[1]//rebin_x, rebin_x ).sum(axis=(1, 3)) # 按步长采样原始边界,得到重bin后的bin边界 rebinned_xedges = orig_xedges[::rebin_x] rebinned_yedges = orig_yedges[::rebin_y] # 组装成和to_numpy()返回结构一致的元组,即可直接绘图 rebinned_h = (rebinned_counts, (rebinned_xedges, rebinned_yedges))
如果需要自定义非等间隔的新bin边界,可以通过numpy.histogram2d加权统计实现:
# 自定义新的bin边界 new_xedges = np.array([0, 1, 3, 5, 10, 20]) new_yedges = np.array([-5, -2, 0, 2, 5]) # 计算原始bin中心,作为加权统计的样本点 orig_xcenters = (orig_xedges[:-1] + orig_xedges[1:]) / 2 orig_ycenters = (orig_yedges[:-1] + orig_yedges[1:]) / 2 x_grid, y_grid = np.meshgrid(orig_xcenters, orig_ycenters) # 按新边界做加权统计,权重为原始bin的计数 rebinned_counts, _, _ = np.histogram2d( x_grid.flatten(), y_grid.flatten(), bins=(new_xedges, new_yedges), weights=orig_counts.flatten() ) rebinned_h = (rebinned_counts, (new_xedges, new_yedges))
常见踩坑说明
- 注意维度顺序:uproot返回的二维计数数组形状为
(n_y_bins, n_x_bins),第一个维度对应y轴、第二个维度对应x轴,手动reshape时不要颠倒顺序,否则会出现绘图翻转、维度不匹配的问题 - 等宽bin场景下,上述两种方法的重bin结果和ROOT原生
TH2::RebinX()/RebinY()结果完全一致 - 重bin后的对象和原始
to_numpy()返回值结构完全相同,所有hist2dplot支持的归一化、色阶、标注参数都可以直接复用,不需要额外调整
内容的提问来源于stack exchange,提问作者nyw
相关产品推荐
相关产品推荐

