Ratio Data vs Model with Stacked and Unstacked Function Components

Imports
Setup
# Create data histogram
data_hist = hist.new.Regular(50, -8, 8).Weight()
data_hist.fill(
np.concatenate(
[
np.random.normal(0, 2, 3500),
np.random.normal(-3, 1, 2000),
np.random.normal(5, 0.5, 200),
]
)
)
_binwidth = data_hist.axes[0].widths[0]
# Define model function components
def f_signal(x):
return 200 * _binwidth * norm.pdf(x, loc=5, scale=0.5)
def f_background1(x):
return 3500 * _binwidth * norm.pdf(x, loc=0, scale=2)
def f_background2(x):
return 2000 * _binwidth * norm.pdf(x, loc=-3, scale=1)
Code
fig, ax_main, ax_comparison = mh.comp.data_model(
data_hist=data_hist,
stacked_components=[f_background1, f_background2],
stacked_labels=["c0", "c1"],
unstacked_components=[f_signal],
unstacked_labels=["Signal"],
unstacked_colors=["#8EBA42"],
xlabel="Observable",
ylabel="Entries",
model_sum_kwargs={"show": True, "label": "Model", "color": "navy"},
comparison="pull",
)
Full code
import hist
import numpy as np
from scipy.stats import norm
import mplhep as mh
np.random.seed(42)
# Create data histogram
data_hist = hist.new.Regular(50, -8, 8).Weight()
data_hist.fill(
np.concatenate(
[
np.random.normal(0, 2, 3500),
np.random.normal(-3, 1, 2000),
np.random.normal(5, 0.5, 200),
]
)
)
_binwidth = data_hist.axes[0].widths[0]
# Define model function components
def f_signal(x):
return 200 * _binwidth * norm.pdf(x, loc=5, scale=0.5)
def f_background1(x):
return 3500 * _binwidth * norm.pdf(x, loc=0, scale=2)
def f_background2(x):
return 2000 * _binwidth * norm.pdf(x, loc=-3, scale=1)
fig, ax_main, ax_comparison = mh.comp.data_model(
data_hist=data_hist,
stacked_components=[f_background1, f_background2],
stacked_labels=["c0", "c1"],
unstacked_components=[f_signal],
unstacked_labels=["Signal"],
unstacked_colors=["#8EBA42"],
xlabel="Observable",
ylabel="Entries",
model_sum_kwargs={"show": True, "label": "Model", "color": "navy"},
comparison="pull",
)