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

如何对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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 20:01:06