Comparing histograms¤
mplhep provides dedicated comparison plotters in the mh.comp module for creating plots with different comparison panels. The following functions are available:
mh.comp.hists(): compare two histograms, plot the main plot and a comparison panel.mh.comp.data_model(): compare a model made of histograms or functions to data, plot the main plot and a comparison panel.mh.comp.comparison(): to only plot the comparison panel given two histograms.mh.comp.get_comparison(): to get the[values, lower_uncertainties, upper_uncertainties]for a given comparison type.
Prerequisites
Throughout this guide the following codeblock is assumed.
Comparing two histograms¤
Available methods¤
To compare two histograms, use mh.comp.hists(). This function takes two histograms as input and creates a figure with a main plot showing both histograms and a comparison panel below it.
The comparison parameter accepts:
ratio: \(\frac{\text{h1}}{\text{h2}}\)split_ratio: same as ratio, but the uncertainties ofh1andh2are shown separately in the comparison panel (used extensively in data/model comparisons, see below)pull: \(\frac{\text{h1} - \text{h2}}{\sqrt{\sigma_{\text{h1}}^2 + \sigma_{\text{h2}}^2}}\)difference: \(\text{h1} - \text{h2}\)relative_difference: \(\frac{\text{h1} - \text{h2}}{\text{h2}}\)asymmetry: \(\frac{\text{h1} - \text{h2}}{\text{h1} + \text{h2}}\)efficiency: \(\frac{\text{h1}}{\text{h2}}\) (with uncertainties from eq.19 here)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='split_ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='pull',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='difference',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='relative_difference',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='asymmetry',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
# Generate sample data and model
x2 = np.random.normal(0, 1, 1000)
x1 = np.random.choice(x2, size=500, replace=False)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1) # h1 needs to be a subset of h2
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='efficiency',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
txt_obj = mh.add_text('plothist', loc='over left', ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='split_ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
txt_obj = mh.add_text('plothist', loc='over left', ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='pull',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
txt_obj = mh.add_text('plothist', loc='over left', ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='difference',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
txt_obj = mh.add_text('plothist', loc='over left', ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='relative_difference',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
txt_obj = mh.add_text('plothist', loc='over left', ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='asymmetry',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
txt_obj = mh.add_text('plothist', loc='over left', ax=ax_main)
# Generate sample data and model
x2 = np.random.normal(0, 1, 1000)
x1 = np.random.choice(x2, size=500, replace=False)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1) # h1 needs to be a subset of h2
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='efficiency',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
txt_obj = mh.add_text('plothist', loc='over left', ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.cms.label(data=True, ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='split_ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.cms.label(data=True, ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='pull',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.cms.label(data=True, ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='difference',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.cms.label(data=True, ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='relative_difference',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.cms.label(data=True, ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='asymmetry',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.cms.label(data=True, ax=ax_main)
# Generate sample data and model
x2 = np.random.normal(0, 1, 1000)
x1 = np.random.choice(x2, size=500, replace=False)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1) # h1 needs to be a subset of h2
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='efficiency',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.cms.label(data=True, ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.atlas.label(data=True, ax=ax_main)
mh.mpl_magic(soft_fail=True)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='split_ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.atlas.label(data=True, ax=ax_main)
mh.mpl_magic(soft_fail=True)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='pull',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.atlas.label(data=True, ax=ax_main)
mh.mpl_magic(soft_fail=True)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='difference',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.atlas.label(data=True, ax=ax_main)
mh.mpl_magic(soft_fail=True)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='relative_difference',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.atlas.label(data=True, ax=ax_main)
mh.mpl_magic(soft_fail=True)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='asymmetry',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.atlas.label(data=True, ax=ax_main)
mh.mpl_magic(soft_fail=True)
# Generate sample data and model
x2 = np.random.normal(0, 1, 1000)
x1 = np.random.choice(x2, size=500, replace=False)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1) # h1 needs to be a subset of h2
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='efficiency',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.atlas.label(data=True, ax=ax_main)
mh.mpl_magic(soft_fail=True)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.lhcb.label(data=True, ax=ax_main)
# Generate sample data and model
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(0, 1.05, 1000)
h1 = hist.new.Reg(25, -4, 4).Weight().fill(x1)
h2 = hist.new.Reg(25, -4, 4).Weight().fill(x2)
# Create comparison plot
fig, ax_main, ax_comp = mh.comp.hists(
h1,
h2,
comparison='split_ratio',
xlabel='Observable [GeV]',
ylabel='Events',
h1_label='h1',
h2_label='h2'
)
mh.lhcb.label(data=True, ax=ax_main)