import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
# --- Academic styling to match the site ---------------------------------------
paper, ink, accent, grey = "#fcfcfa", "#22262b", "#3a5a7a", "#8a8f96"
plt.rcParams.update({
"font.family": "serif",
"font.size": 11,
"axes.edgecolor": ink,
"axes.linewidth": 0.8,
"figure.facecolor": paper,
"axes.facecolor": paper,
"savefig.facecolor": paper,
})
# --- Illustrative H -> gamma gamma model --------------------------------------
# Falling background + a narrow resonance at m_H = 125 GeV. Numbers are
# representative, chosen for a clear bump; NOT fitted to real data.
binw = 2.0
edges = np.arange(100.0, 160.0 + binw, binw) # 2 GeV bins over [100, 160] GeV
centers = 0.5 * (edges[:-1] + edges[1:])
rng = np.random.default_rng(125)
def background(m):
return 2600.0 * np.exp(-0.045 * (m - 100.0))
def signal(m, mH=125.0, sigma=1.7, nsig=1100.0):
gauss = np.exp(-0.5 * ((m - mH) / sigma) ** 2) / (sigma * np.sqrt(2 * np.pi))
return nsig * gauss * binw # -> expected events per 2 GeV bin
bkg = background(centers)
expect = bkg + signal(centers)
data = rng.poisson(expect).astype(float) # pseudo-data
err = np.sqrt(data)
mfine = np.linspace(100.0, 160.0, 400)
bkg_fine, sig_fine = background(mfine), signal(mfine)
# --- Two-panel figure ---------------------------------------------------------
fig = plt.figure(figsize=(6.4, 5.2))
gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1], hspace=0.08)
ax, axr = fig.add_subplot(gs[0]), None
axr = fig.add_subplot(gs[1], sharex=ax)
ax.errorbar(centers, data, yerr=err, fmt="o", ms=4, color=ink, ecolor=grey,
elinewidth=0.9, capsize=0, label="Data (synthetic)", zorder=3)
ax.plot(mfine, bkg_fine, "--", color=grey, lw=1.6, label="Background fit", zorder=2)
ax.plot(mfine, bkg_fine + sig_fine, "-", color=accent, lw=2.0,
label="Signal + background fit", zorder=2)
ax.axvline(125, color=accent, lw=0.8, ls=":", alpha=0.6, zorder=1)
ax.set_ylabel("Events / 2 GeV")
ax.set_ylim(bottom=0)
ax.legend(frameon=False, fontsize=9, loc="upper right")
ax.tick_params(labelbottom=False)
ax.set_title(r"$H \rightarrow \gamma\gamma$ (illustrative, synthetic data)",
fontsize=12, pad=8)
axr.errorbar(centers, data - bkg, yerr=err, fmt="o", ms=4, color=ink, ecolor=grey,
elinewidth=0.9, capsize=0, zorder=3)
axr.plot(mfine, sig_fine, "-", color=accent, lw=2.0, zorder=2)
axr.axhline(0, color=grey, lw=0.8, zorder=1)
axr.set_ylabel(r"Data $-$ Bkg")
axr.set_xlabel(r"$m_{\gamma\gamma}$ [GeV]")
for a in (ax, axr):
a.spines[["top", "right"]].set_visible(False)
a.grid(axis="y", color=grey, alpha=0.15, lw=0.6)
a.set_xlim(100, 160)
plt.show()