diff --git a/examples/1d_histograms/1d_comparison_asymmetry.py b/examples/1d_histograms/1d_comparison_asymmetry.py index 2103ac79..6980b009 100644 --- a/examples/1d_histograms/1d_comparison_asymmetry.py +++ b/examples/1d_histograms/1d_comparison_asymmetry.py @@ -9,7 +9,6 @@ # --8<-- [start:imports] import hist import numpy as np -from hist import Hist import mplhep as mh @@ -21,11 +20,9 @@ x1 = np.r_[np.random.normal(0.4, 0.1, 5000), np.random.normal(0.7, 0.1, 5000)] x2 = np.r_[np.random.normal(0.4, 0.1, 1000), np.random.normal(0.7, 0.11, 7000)] -# Create and fill histograms" -h1 = Hist(hist.axis.Regular(50, 0, 1), storage=hist.storage.Weight()) # Long interface -h2 = hist.new.Regular(50, 0, 1).Weight() # Shorthand interface -h1.fill(x1) -h2.fill(x2) +# Create and fill histograms +h1 = hist.new.Regular(50, 0, 1).Weight().fill(x1) +h2 = hist.new.Regular(50, 0, 1).Weight().fill(x2) # --8<-- [end:setup] # --8<-- [start:plot_body] diff --git a/examples/1d_histograms/1d_comparison_difference.py b/examples/1d_histograms/1d_comparison_difference.py index 89d78eb8..405208c8 100644 --- a/examples/1d_histograms/1d_comparison_difference.py +++ b/examples/1d_histograms/1d_comparison_difference.py @@ -9,7 +9,6 @@ # --8<-- [start:imports] import hist import numpy as np -from hist import Hist import mplhep as mh @@ -21,17 +20,13 @@ x1 = np.r_[np.random.normal(0.4, 0.1, 5000), np.random.normal(0.7, 0.1, 5000)] x2 = np.r_[np.random.normal(0.4, 0.1, 1000), np.random.normal(0.7, 0.11, 7000)] -# Create and fill histograms" -h1 = Hist(hist.axis.Regular(50, 0, 1), storage=hist.storage.Weight()) # Long interface -h2 = hist.new.Regular(50, 0, 1).Weight() # Shorthand interface -h1.fill(x1) -h2.fill(x2) +# Create and fill histograms +h1 = hist.new.Regular(50, 0, 1).Weight().fill(x1) +h2 = hist.new.Regular(50, 0, 1).Weight().fill(x2) # --8<-- [end:setup] # --8<-- [start:plot_body] -from mplhep import add_text - fig, ax_main, ax_comparison = mh.comp.hists( h1, h2, @@ -42,13 +37,13 @@ comparison="difference", # <-- ) -add_text( +mh.add_text( "Comparison of two hist with difference plot", ax=ax_main, fontsize="small", loc="over left", ) -add_text("Difference ax", ax=ax_comparison, loc="over right", fontsize="small") +mh.add_text("Difference ax", ax=ax_comparison, loc="over right", fontsize="small") # --8<-- [end:plot_body] # --8<-- [end:full_code] diff --git a/examples/1d_histograms/1d_comparison_efficiency.py b/examples/1d_histograms/1d_comparison_efficiency.py index 7987332f..e0c83cf4 100644 --- a/examples/1d_histograms/1d_comparison_efficiency.py +++ b/examples/1d_histograms/1d_comparison_efficiency.py @@ -9,7 +9,6 @@ # --8<-- [start:imports] import hist import numpy as np -from hist import Hist import mplhep as mh @@ -22,16 +21,11 @@ x_sample = x_total[:7500] # 75% subset # Create and fill histograms -h_sample = Hist( - hist.axis.Regular(50, 0, 1), storage=hist.storage.Weight() -) # Long interface -h_total = hist.new.Regular(50, 0, 1).Weight() # Shorthand interface -h_sample.fill(x_sample) -h_total.fill(x_total) +h_sample = hist.new.Regular(50, 0, 1).Weight().fill(x_sample) +h_total = hist.new.Regular(50, 0, 1).Weight().fill(x_total) # --8<-- [end:setup] # --8<-- [start:plot_body] -### fig, ax_main, ax_comparison = mh.comp.hists( h_sample, h_total, diff --git a/examples/1d_histograms/1d_comparison_only_efficiency.py b/examples/1d_histograms/1d_comparison_only_efficiency.py index 4c694306..e4e9b0d2 100644 --- a/examples/1d_histograms/1d_comparison_only_efficiency.py +++ b/examples/1d_histograms/1d_comparison_only_efficiency.py @@ -10,7 +10,6 @@ import hist import matplotlib.pyplot as plt import numpy as np -from hist import Hist import mplhep as mh @@ -23,16 +22,11 @@ x_sample = x_total[:7500] # 75% subset # Create and fill histograms -h_sample = Hist( - hist.axis.Regular(50, 0, 1), storage=hist.storage.Weight() -) # Long interface -h_total = hist.new.Regular(50, 0, 1).Weight() # Shorthand interface -h_sample.fill(x_sample) -h_total.fill(x_total) +h_sample = hist.new.Regular(50, 0, 1).Weight().fill(x_sample) +h_total = hist.new.Regular(50, 0, 1).Weight().fill(x_total) # --8<-- [end:setup] # --8<-- [start:plot_body] -# Plot comparison using efficiency fig, ax = plt.subplots() mh.comp.comparison(h_sample, h_total, ax=ax, xlabel="Variable", comparison="efficiency") diff --git a/examples/1d_histograms/1d_comparison_pull.py b/examples/1d_histograms/1d_comparison_pull.py index e024a5ea..87921281 100644 --- a/examples/1d_histograms/1d_comparison_pull.py +++ b/examples/1d_histograms/1d_comparison_pull.py @@ -9,7 +9,6 @@ # --8<-- [start:imports] import hist import numpy as np -from hist import Hist import mplhep as mh @@ -22,14 +21,11 @@ x2 = np.r_[np.random.normal(0.4, 0.1, 1000), np.random.normal(0.7, 0.11, 7000)] # Create and fill histograms -h1 = Hist(hist.axis.Regular(50, 0, 1), storage=hist.storage.Weight()) # Long interface -h2 = hist.new.Regular(50, 0, 1).Weight() # Shorthand interface -h1.fill(x1) -h2.fill(x2) +h1 = hist.new.Regular(50, 0, 1).Weight().fill(x1) +h2 = hist.new.Regular(50, 0, 1).Weight().fill(x2) # --8<-- [end:setup] # --8<-- [start:plot_body] -### fig, ax_main, ax_comparison = mh.comp.hists( h1, h2, diff --git a/examples/1d_histograms/1d_comparison_ratio.py b/examples/1d_histograms/1d_comparison_ratio.py index 63e34b6d..b0c35520 100644 --- a/examples/1d_histograms/1d_comparison_ratio.py +++ b/examples/1d_histograms/1d_comparison_ratio.py @@ -9,7 +9,6 @@ # --8<-- [start:imports] import hist import numpy as np -from hist import Hist import mplhep as mh @@ -22,14 +21,11 @@ x2 = np.r_[np.random.normal(0.4, 0.1, 1000), np.random.normal(0.7, 0.11, 7000)] # Create and fill histograms -h1 = Hist(hist.axis.Regular(50, 0, 1), storage=hist.storage.Weight()) # Long interface -h2 = hist.new.Regular(50, 0, 1).Weight() # Shorthand interface -h1.fill(x1) -h2.fill(x2) +h1 = hist.new.Regular(50, 0, 1).Weight().fill(x1) +h2 = hist.new.Regular(50, 0, 1).Weight().fill(x2) # --8<-- [end:setup] # --8<-- [start:plot_body] -### fig, ax_main, ax_comparison = mh.comp.hists( h1, h2, diff --git a/examples/1d_histograms/1d_comparison_relative_difference.py b/examples/1d_histograms/1d_comparison_relative_difference.py index 3a88166e..ceb19f70 100644 --- a/examples/1d_histograms/1d_comparison_relative_difference.py +++ b/examples/1d_histograms/1d_comparison_relative_difference.py @@ -9,7 +9,6 @@ # --8<-- [start:imports] import hist import numpy as np -from hist import Hist import mplhep as mh @@ -22,14 +21,11 @@ x2 = np.r_[np.random.normal(0.4, 0.1, 1000), np.random.normal(0.7, 0.11, 7000)] # Create and fill histograms -h1 = Hist(hist.axis.Regular(50, 0, 1), storage=hist.storage.Weight()) # Long interface -h2 = hist.new.Regular(50, 0, 1).Weight() # Shorthand interface -h1.fill(x1) -h2.fill(x2) +h1 = hist.new.Regular(50, 0, 1).Weight().fill(x1) +h2 = hist.new.Regular(50, 0, 1).Weight().fill(x2) # --8<-- [end:setup] # --8<-- [start:plot_body] -### fig, ax_main, ax_comparison = mh.comp.hists( h1, h2, diff --git a/examples/1d_histograms/1d_comparison_split_ratio.py b/examples/1d_histograms/1d_comparison_split_ratio.py index f57c5101..f51e715f 100644 --- a/examples/1d_histograms/1d_comparison_split_ratio.py +++ b/examples/1d_histograms/1d_comparison_split_ratio.py @@ -9,7 +9,6 @@ # --8<-- [start:imports] import hist import numpy as np -from hist import Hist import mplhep as mh @@ -22,14 +21,11 @@ x2 = np.r_[np.random.normal(0.4, 0.1, 1000), np.random.normal(0.7, 0.11, 7000)] # Create and fill histograms -h1 = Hist(hist.axis.Regular(50, 0, 1), storage=hist.storage.Weight()) # Long interface -h2 = hist.new.Regular(50, 0, 1).Weight() # Shorthand interface -h1.fill(x1) -h2.fill(x2) +h1 = hist.new.Regular(50, 0, 1).Weight().fill(x1) +h2 = hist.new.Regular(50, 0, 1).Weight().fill(x2) # --8<-- [end:setup] # --8<-- [start:plot_body] -### fig, ax_main, ax_comparison = mh.comp.hists( h1, h2, diff --git a/examples/model_ex/model_all_comparisons.py b/examples/model_ex/model_all_comparisons.py index ef33d4e3..628f6f25 100644 --- a/examples/model_ex/model_all_comparisons.py +++ b/examples/model_ex/model_all_comparisons.py @@ -7,80 +7,58 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -from plothist_utils import get_dummy_data - -df = get_dummy_data() - +import hist +import matplotlib.pyplot as plt +import numpy as np import seaborn as sns import mplhep as mh +np.random.seed(42) # --8<-- [end:imports] # --8<-- [start:setup] -# Define the histograms - -key = "variable_1" -x_range = (-9, 12) -category = "category" - -# Define masks -signal_mask = df[category] == 7 -data_mask = df[category] == 8 - -background_categories = [0, 1, 2] -background_categories_labels = [f"c{i}" for i in background_categories] -background_categories_colors = sns.color_palette( - "cubehelix", len(background_categories) +# Create data histogram with mixed components +data_hist = hist.new.Regular(50, -8, 8).Weight() +data_hist.fill( + np.concatenate( + [ + np.random.normal(0, 2, 3000), + np.random.normal(-3, 0.8, 1500), + np.random.normal(-2, 1.5, 1200), + np.random.normal(0, 0.5, 300), + ] + ) ) -background_masks = [df[category] == p for p in background_categories] - -# Make histograms -import hist -from hist import Hist +# Create background component histograms +background_hists = [ + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(0, 2, 3500)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-3, 0.8, 1800)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-2, 1.5, 1400)), +] -axis = hist.axis.Regular(50, x_range[0], x_range[1]) - -data_hist = Hist(axis, storage=hist.storage.Weight()) -signal_hist = Hist(axis, storage=hist.storage.Weight()) -background_hists = [] - -data_hist.fill(df[key][data_mask]) -signal_hist.fill(df[key][signal_mask]) - -for mask in background_masks: - h_bkg = Hist(axis, storage=hist.storage.Weight()) - h_bkg.fill(df[key][mask]) - background_hists.append(h_bkg) - -# Optional: scale to data -background_scaling_factor = data_hist.sum().value / sum(background_hists).sum().value -background_hists = [background_scaling_factor * h for h in background_hists] +# Scale backgrounds to match data +scale = data_hist.sum().value / sum(background_hists).sum().value +background_hists = [scale * h for h in background_hists] # --8<-- [end:setup] # --8<-- [start:plot_body] -### -import matplotlib.pyplot as plt - -from mplhep import comp - fig, axes = plt.subplots( - nrows=6, - figsize=(6, 13), - gridspec_kw={"height_ratios": [3, 1, 1, 1, 1, 1]}, + nrows=6, figsize=(6, 13), gridspec_kw={"height_ratios": [3, 1, 1, 1, 1, 1]} ) fig.subplots_adjust(hspace=0.3) + +# Hide x-axis labels for all but the bottom plot for ax in axes[:-1]: ax.xaxis.set_ticklabels([]) ax.set_xlabel(" ") -background_sum = sum(background_hists) -comp.data_model( +mh.comp.data_model( data_hist=data_hist, stacked_components=background_hists, - stacked_labels=background_categories_labels, - stacked_colors=background_categories_colors, + stacked_labels=["c0", "c1", "c2"], + stacked_colors=sns.color_palette("cubehelix", 3), xlabel="", ylabel="Entries", comparison="ratio", @@ -99,28 +77,27 @@ r' $\mathbf{→}$ comparison = "ratio"', ax=axes[1], loc="over left", fontsize=13 ) -for k_comp, comparison in enumerate( +# Add remaining comparison types +for k, comp in enumerate( ["split_ratio", "pull", "relative_difference", "difference"], start=2 ): - ax_comparison = axes[k_comp] - - comp.comparison( + mh.comp.comparison( data_hist, - background_sum, - ax=ax_comparison, - comparison=comparison, + sum(background_hists), + ax=axes[k], + comparison=comp, xlabel="", h1_label="Data", h2_label="MC", h1_w2method="poisson", ) mh.add_text( - rf' $\mathbf{{→}}$ comparison = "{comparison}"', - ax=ax_comparison, + rf' $\mathbf{{→}}$ comparison = "{comp}"', + ax=axes[k], fontsize=13, loc="over left", ) - mh.set_fitting_ylabel_fontsize(ax_comparison) + mh.set_fitting_ylabel_fontsize(axes[k]) axes[-1].set_xlabel("Observable") # --8<-- [end:plot_body] diff --git a/examples/model_ex/model_all_comparisons_no_model_unc.py b/examples/model_ex/model_all_comparisons_no_model_unc.py index d3eb16a2..01d49fdd 100644 --- a/examples/model_ex/model_all_comparisons_no_model_unc.py +++ b/examples/model_ex/model_all_comparisons_no_model_unc.py @@ -11,7 +11,6 @@ import matplotlib.pyplot as plt import numpy as np import seaborn as sns -from hist import Hist import mplhep as mh @@ -35,14 +34,13 @@ np.random.normal(0, 2.5, 3500), # Less background here np.random.normal(3, 1.2, 1800), # Similar background np.random.normal(-1, 1.8, 1400), # Similar background - np.random.normal(5, 0.8, 800), # Clear signal peak + np.random.normal(0, 0.8, 500), # Clear signal peak np.random.normal(-3, 0.5, 200), # Some deficit here (under-predicted) ] ) # Create histograms -data_hist = Hist(hist.axis.Regular(50, -8, 8), storage=hist.storage.Weight()) -data_hist.fill(data_data) +data_hist = hist.new.Regular(50, -8, 8).Weight().fill(data_data) background_hists = [ hist.new.Regular(50, -8, 8).Weight().fill(bkg1_data), diff --git a/examples/model_ex/model_examples_pull.py b/examples/model_ex/model_examples_pull.py index c16aae43..32bdbf87 100644 --- a/examples/model_ex/model_examples_pull.py +++ b/examples/model_ex/model_examples_pull.py @@ -7,66 +7,48 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -from plothist_utils import get_dummy_data - -df = get_dummy_data() - +import hist +import numpy as np import seaborn as sns +import mplhep as mh + +np.random.seed(42) # --8<-- [end:imports] # --8<-- [start:setup] -# Define the histograms - -key = "variable_1" -x_range = (-9, 12) -category = "category" - -# Define masks -signal_mask = df[category] == 7 -data_mask = df[category] == 8 - -background_categories = [0, 1, 2] -background_categories_labels = [f"c{i}" for i in background_categories] -background_categories_colors = sns.color_palette( - "cubehelix", len(background_categories) +# Create data histogram +data_hist = hist.new.Regular(50, -8, 8).Weight() +data_hist.fill( + np.concatenate( + [ + np.random.normal(0, 2, 2000), + np.random.normal(-3, 0.8, 1500), + np.random.normal(-2, 1.5, 1200), + np.random.normal(0, 0.5, 500), + ] + ) ) -background_masks = [df[category] == p for p in background_categories] +# Create background histograms +background_hists = [ + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(0, 2, 3500)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-3, 0.8, 1800)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-2, 1.5, 1400)), +] -# Make histograms -import hist -from hist import Hist - -axis = hist.axis.Regular(50, x_range[0], x_range[1]) - -data_hist = Hist(axis, storage=hist.storage.Weight()) -signal_hist = Hist(axis, storage=hist.storage.Weight()) -background_hists = [] - -data_hist.fill(df[key][data_mask]) -signal_hist.fill(df[key][signal_mask]) - -for mask in background_masks: - h_bkg = Hist(axis, storage=hist.storage.Weight()) - h_bkg.fill(df[key][mask]) - background_hists.append(h_bkg) - -# Optional: scale to data -background_scaling_factor = data_hist.sum().value / sum(background_hists).sum().value -background_hists = [background_scaling_factor * h for h in background_hists] +# Scale backgrounds to match data +scale = data_hist.sum().value / sum(background_hists).sum().value +background_hists = [scale * h for h in background_hists] # --8<-- [end:setup] # --8<-- [start:plot_body] -### -from mplhep import comp - -fig, ax_main, ax_comparison = comp.data_model( +fig, ax_main, ax_comparison = mh.comp.data_model( data_hist=data_hist, stacked_components=background_hists, - stacked_labels=background_categories_labels, - stacked_colors=background_categories_colors, - xlabel=rf"${key}\,\,[TeV/c^2]$", + stacked_labels=["c0", "c1", "c2"], + stacked_colors=sns.color_palette("cubehelix", 3), + xlabel=r"$m_{\ell\ell}\,\,[TeV/c^2]$", ylabel="Candidates per 0.42 $TeV/c^2$", comparison="pull", ) diff --git a/examples/model_ex/model_examples_pull_no_model_unc.py b/examples/model_ex/model_examples_pull_no_model_unc.py index e40a8bcf..9ea651ba 100644 --- a/examples/model_ex/model_examples_pull_no_model_unc.py +++ b/examples/model_ex/model_examples_pull_no_model_unc.py @@ -7,66 +7,48 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -from plothist_utils import get_dummy_data - -df = get_dummy_data() - +import hist +import numpy as np import seaborn as sns +import mplhep as mh + +np.random.seed(42) # --8<-- [end:imports] # --8<-- [start:setup] -# Define the histograms - -key = "variable_1" -x_range = (-9, 12) -category = "category" - -# Define masks -signal_mask = df[category] == 7 -data_mask = df[category] == 8 - -background_categories = [0, 1, 2] -background_categories_labels = [f"c{i}" for i in background_categories] -background_categories_colors = sns.color_palette( - "cubehelix", len(background_categories) +# Create data histogram +data_hist = hist.new.Regular(50, -8, 8).Weight() +data_hist.fill( + np.concatenate( + [ + np.random.normal(0, 2, 2000), + np.random.normal(-3, 0.8, 1500), + np.random.normal(-2, 1.5, 1200), + np.random.normal(0, 0.5, 500), + ] + ) ) -background_masks = [df[category] == p for p in background_categories] +# Create background histograms +background_hists = [ + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(0, 2, 3500)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-3, 0.8, 1800)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-2, 1.5, 1400)), +] -# Make histograms -import hist -from hist import Hist - -axis = hist.axis.Regular(50, x_range[0], x_range[1]) - -data_hist = Hist(axis, storage=hist.storage.Weight()) -signal_hist = Hist(axis, storage=hist.storage.Weight()) -background_hists = [] - -data_hist.fill(df[key][data_mask]) -signal_hist.fill(df[key][signal_mask]) - -for mask in background_masks: - h_bkg = Hist(axis, storage=hist.storage.Weight()) - h_bkg.fill(df[key][mask]) - background_hists.append(h_bkg) - -# Optional: scale to data -background_scaling_factor = data_hist.sum().value / sum(background_hists).sum().value -background_hists = [background_scaling_factor * h for h in background_hists] +# Scale backgrounds to match data +scale = data_hist.sum().value / sum(background_hists).sum().value +background_hists = [scale * h for h in background_hists] # --8<-- [end:setup] # --8<-- [start:plot_body] -### -from mplhep import comp - -fig, ax_main, ax_comparison = comp.data_model( +fig, ax_main, ax_comparison = mh.comp.data_model( data_hist=data_hist, stacked_components=background_hists, - stacked_labels=background_categories_labels, - stacked_colors=background_categories_colors, - xlabel=rf"${key}\,\,[eV/c^2]$", + stacked_labels=["c0", "c1", "c2"], + stacked_colors=sns.color_palette("cubehelix", 3), + xlabel=r"$m_{\ell\ell}\,\,[TeV/c^2]$", ylabel=r"Hits in the LMN per $4.2\times 10^{-1}\,\,eV/c^2$", comparison="pull", model_uncertainty=False, # <-- diff --git a/examples/model_ex/model_examples_stacked.py b/examples/model_ex/model_examples_stacked.py index fd669f89..f8f1cc30 100644 --- a/examples/model_ex/model_examples_stacked.py +++ b/examples/model_ex/model_examples_stacked.py @@ -7,81 +7,56 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -from plothist_utils import get_dummy_data - -df = get_dummy_data() - +import hist +import numpy as np import seaborn as sns +import mplhep as mh + +np.random.seed(42) # --8<-- [end:imports] # --8<-- [start:setup] -# Define the histograms - -key = "variable_1" -x_range = (-9, 12) -category = "category" - -# Define masks -signal_mask = df[category] == 7 -data_mask = df[category] == 8 - -background_categories = [0, 1, 2] -background_categories_labels = [f"c{i}" for i in background_categories] -background_categories_colors = sns.color_palette( - "cubehelix", len(background_categories) +# Create data histogram +data_hist = hist.new.Regular(50, -8, 8).Weight() +data_hist.fill( + np.concatenate( + [ + np.random.normal(0, 2, 3000), + np.random.normal(-3, 0.8, 1500), + np.random.normal(-2, 1.5, 1200), + np.random.normal(0, 0.5, 500), + ] + ) ) -background_masks = [df[category] == p for p in background_categories] - -# Make histograms -import hist -from hist import Hist - -axis = hist.axis.Regular(50, x_range[0], x_range[1]) - -data_hist = Hist(axis, storage=hist.storage.Weight()) -signal_hist = Hist(axis, storage=hist.storage.Weight()) -background_hists = [] - -data_hist.fill(df[key][data_mask]) -signal_hist.fill(df[key][signal_mask]) +# Create background histograms +background_hists = [ + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(0, 2, 3500)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-3, 0.8, 1800)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-2, 1.5, 1400)), +] -for mask in background_masks: - h_bkg = Hist(axis, storage=hist.storage.Weight()) - h_bkg.fill(df[key][mask]) - background_hists.append(h_bkg) +# Scale backgrounds to match data +scale = data_hist.sum().value / sum(background_hists).sum().value +background_hists = [scale * h for h in background_hists] -# Optional: scale to data -background_scaling_factor = data_hist.sum().value / sum(background_hists).sum().value -background_hists = [background_scaling_factor * h for h in background_hists] - -signal_scaling_factor = data_hist.sum().value / signal_hist.sum().value -signal_hist *= signal_scaling_factor +# Create signal histogram (not part of the model) +signal_hist = hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-1, 0.5, 400)) # --8<-- [end:setup] # --8<-- [start:plot_body] -### -from mplhep import comp, histplot - -fig, ax_main, ax_comparison = comp.data_model( +fig, ax_main, ax_comparison = mh.comp.data_model( data_hist=data_hist, stacked_components=background_hists, - stacked_labels=background_categories_labels, - stacked_colors=background_categories_colors, - xlabel=key, + stacked_labels=["c0", "c1", "c2"], + stacked_colors=sns.color_palette("cubehelix", 3), + xlabel="Observable", ylabel="Entries", ) # Signal histogram not part of the model and therefore not included in the comparison -histplot( - signal_hist, - ax=ax_main, - color="red", - label="Signal", - histtype="step", -) - +mh.histplot(signal_hist, ax=ax_main, color="red", label="Signal", histtype="step") ax_main.legend() # --8<-- [end:plot_body] diff --git a/examples/model_ex/model_examples_stacked_unstacked.py b/examples/model_ex/model_examples_stacked_unstacked.py index 20807f1b..f051da34 100644 --- a/examples/model_ex/model_examples_stacked_unstacked.py +++ b/examples/model_ex/model_examples_stacked_unstacked.py @@ -7,69 +7,51 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -from plothist_utils import get_dummy_data - -df = get_dummy_data() - +import hist +import numpy as np import seaborn as sns +import mplhep as mh + +np.random.seed(42) # --8<-- [end:imports] # --8<-- [start:setup] -# Define the histograms - -key = "variable_1" -x_range = (-9, 12) -category = "category" - -# Define masks -signal_mask = df[category] == 7 -data_mask = df[category] == 8 - -background_categories = [0, 1, 2] -background_categories_labels = [f"c{i}" for i in background_categories] -background_categories_colors = sns.color_palette( - "cubehelix", len(background_categories) +# Create data histogram +data_hist = hist.new.Regular(50, -8, 8).Weight() +data_hist.fill( + np.concatenate( + [ + np.random.normal(0, 2, 3000), + np.random.normal(-3, 0.8, 1500), + np.random.normal(-2, 1.5, 1200), + np.random.normal(0, 0.5, 500), + ] + ) ) -background_masks = [df[category] == p for p in background_categories] +# Create background histograms +background_hists = [ + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(0, 2, 3500)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-3, 0.8, 1800)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-2, 1.5, 1400)), +] -# Make histograms -import hist -from hist import Hist - -axis = hist.axis.Regular(50, x_range[0], x_range[1]) - -data_hist = Hist(axis, storage=hist.storage.Weight()) -signal_hist = Hist(axis, storage=hist.storage.Weight()) -background_hists = [] - -data_hist.fill(df[key][data_mask]) -signal_hist.fill(df[key][signal_mask]) - -for mask in background_masks: - h_bkg = Hist(axis, storage=hist.storage.Weight()) - h_bkg.fill(df[key][mask]) - background_hists.append(h_bkg) - -# Optional: scale to data -background_scaling_factor = data_hist.sum().value / sum(background_hists).sum().value -background_hists = [background_scaling_factor * h for h in background_hists] +# Scale backgrounds to match data +scale = data_hist.sum().value / sum(background_hists).sum().value +background_hists = [scale * h for h in background_hists] # --8<-- [end:setup] # --8<-- [start:plot_body] -### -from mplhep import comp - -fig, ax_main, ax_comparison = comp.data_model( +fig, ax_main, ax_comparison = mh.comp.data_model( data_hist=data_hist, stacked_components=background_hists[:2], - stacked_labels=background_categories_labels[:2], - stacked_colors=background_categories_colors[:2], + stacked_labels=["c0", "c1"], + stacked_colors=sns.color_palette("cubehelix", 3)[:2], unstacked_components=background_hists[2:], - unstacked_labels=background_categories_labels[2:], - unstacked_colors=background_categories_colors[2:], - xlabel=key, + unstacked_labels=["c2"], + unstacked_colors=[sns.color_palette("cubehelix", 3)[2]], + xlabel="Observable", ylabel="Entries", model_sum_kwargs={"show": True, "label": "Model", "color": "navy"}, comparison_ylim=(0.5, 1.5), diff --git a/examples/model_ex/model_examples_unstacked.py b/examples/model_ex/model_examples_unstacked.py index 53bffca0..0be18341 100644 --- a/examples/model_ex/model_examples_unstacked.py +++ b/examples/model_ex/model_examples_unstacked.py @@ -7,66 +7,48 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -from plothist_utils import get_dummy_data - -df = get_dummy_data() - +import hist +import numpy as np import seaborn as sns +import mplhep as mh + +np.random.seed(42) # --8<-- [end:imports] # --8<-- [start:setup] -# Define the histograms - -key = "variable_1" -x_range = (-9, 12) -category = "category" - -# Define masks -signal_mask = df[category] == 7 -data_mask = df[category] == 8 - -background_categories = [0, 1, 2] -background_categories_labels = [f"c{i}" for i in background_categories] -background_categories_colors = sns.color_palette( - "cubehelix", len(background_categories) +# Create data histogram +data_hist = hist.new.Regular(50, -8, 8).Weight() +data_hist.fill( + np.concatenate( + [ + np.random.normal(0, 2, 3000), + np.random.normal(-3, 0.8, 1500), + np.random.normal(-2, 1.5, 1200), + np.random.normal(0, 0.5, 500), + ] + ) ) -background_masks = [df[category] == p for p in background_categories] +# Create background histograms +background_hists = [ + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(0, 2, 3500)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-3, 0.8, 1800)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-2, 1.5, 1400)), +] -# Make histograms -import hist -from hist import Hist - -axis = hist.axis.Regular(50, x_range[0], x_range[1]) - -data_hist = Hist(axis, storage=hist.storage.Weight()) -signal_hist = Hist(axis, storage=hist.storage.Weight()) -background_hists = [] - -data_hist.fill(df[key][data_mask]) -signal_hist.fill(df[key][signal_mask]) - -for mask in background_masks: - h_bkg = Hist(axis, storage=hist.storage.Weight()) - h_bkg.fill(df[key][mask]) - background_hists.append(h_bkg) - -# Optional: scale to data -background_scaling_factor = data_hist.sum().value / sum(background_hists).sum().value -background_hists = [background_scaling_factor * h for h in background_hists] +# Scale backgrounds to match data +scale = data_hist.sum().value / sum(background_hists).sum().value +background_hists = [scale * h for h in background_hists] # --8<-- [end:setup] # --8<-- [start:plot_body] -### -from mplhep import comp - -fig, ax_main, ax_comparison = comp.data_model( +fig, ax_main, ax_comparison = mh.comp.data_model( data_hist=data_hist, unstacked_components=background_hists, - unstacked_labels=background_categories_labels, - unstacked_colors=background_categories_colors, - xlabel=key, + unstacked_labels=["c0", "c1", "c2"], + unstacked_colors=sns.color_palette("cubehelix", 3), + xlabel="Observable", ylabel="Entries", model_sum_kwargs={"label": "Sum(hists)", "color": "navy"}, comparison_ylim=[0.5, 1.5], diff --git a/examples/model_ex/model_with_stacked_and_unstacked_function_components.py b/examples/model_ex/model_with_stacked_and_unstacked_function_components.py index 2a710acf..6aa7d712 100644 --- a/examples/model_ex/model_with_stacked_and_unstacked_function_components.py +++ b/examples/model_ex/model_with_stacked_and_unstacked_function_components.py @@ -7,22 +7,17 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -key = "variable_1" -range = (-9, 12) - -background_categories = [0, 1, 2] -background_categories_labels = [f"c{i}" for i in background_categories] - - -# Define some random functions that will be used as model components with functions from scipy.stats import norm +import mplhep as mh + # --8<-- [end:imports] # --8<-- [start:setup] +# Define model function components def f_signal(x): - return 1000 * norm.pdf(x, loc=0.5, scale=3) + return 600 * norm.pdf(x, loc=0.2, scale=3) def f_background1(x): @@ -30,28 +25,25 @@ def f_background1(x): def f_background2(x): - return 3000 * norm.pdf(x, loc=-1.8, scale=1.8) + return 3000 * norm.pdf(x, loc=-3.2, scale=1.2) # --8<-- [end:setup] # --8<-- [start:plot_body] -### -from mplhep import add_text, model - -fig, ax = model( +fig, ax = mh.model( stacked_components=[f_background1, f_background2], - stacked_labels=background_categories_labels[:2], + stacked_labels=["c0", "c1"], unstacked_components=[f_signal], unstacked_labels=["Signal"], unstacked_colors=["black"], - xlabel=key, - ylabel=f"f({key})", + xlabel="Observable", + ylabel="f(Observable)", model_sum_kwargs={"show": True, "label": "Model", "color": "navy"}, - function_range=range, + function_range=(-9, 12), ) -add_text("Model made of functions", ax=ax, loc="over left", fontsize="small") +mh.add_text("Model made of functions", ax=ax, loc="over left", fontsize="small") # --8<-- [end:plot_body] # --8<-- [end:full_code] diff --git a/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py b/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py index 33f0cee7..62ab53b2 100644 --- a/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py +++ b/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py @@ -7,82 +7,43 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -from plothist_utils import get_dummy_data - -df = get_dummy_data() - +import hist +import numpy as np import seaborn as sns +import mplhep as mh + +np.random.seed(42) # --8<-- [end:imports] # --8<-- [start:setup] -# Define the histograms - -key = "variable_1" -x_range = (-9, 12) -category = "category" - -# Define masks -signal_mask = df[category] == 7 -data_mask = df[category] == 8 - -background_categories = [0, 1, 2] -background_categories_labels = [f"c{i}" for i in background_categories] -background_categories_colors = sns.color_palette( - "cubehelix", len(background_categories) -) - -background_masks = [df[category] == p for p in background_categories] - -# Make histograms -import hist -from hist import Hist - -axis = hist.axis.Regular(50, x_range[0], x_range[1]) - -data_hist = Hist(axis, storage=hist.storage.Weight()) -signal_hist = Hist(axis, storage=hist.storage.Weight()) -background_hists = [] - -data_hist.fill(df[key][data_mask]) -signal_hist.fill(df[key][signal_mask]) - -for mask in background_masks: - h_bkg = Hist(axis, storage=hist.storage.Weight()) - h_bkg.fill(df[key][mask]) - background_hists.append(h_bkg) - -# Optional: scale to data -background_scaling_factor = data_hist.sum().value / sum(background_hists).sum().value -background_hists = [background_scaling_factor * h for h in background_hists] - -signal_scaling_factor = data_hist.sum().value / signal_hist.sum().value -signal_hist *= signal_scaling_factor +# Create background histograms +background_hists = [ + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(0, 2, 3500)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-3, 0.8, 1800)), + hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(-2, 1.5, 1400)), +] + +# Create signal histogram +signal_hist = hist.new.Regular(50, -8, 8).Weight().fill(np.random.normal(0, 0.5, 500)) # --8<-- [end:setup] # --8<-- [start:plot_body] -### -from mplhep import add_text, model - -fig, ax = model( +fig, ax = mh.model( stacked_components=background_hists, - stacked_labels=background_categories_labels, - stacked_colors=background_categories_colors, + stacked_labels=["c0", "c1", "c2"], + stacked_colors=sns.color_palette("cubehelix", 3), unstacked_components=[signal_hist], unstacked_labels=["Signal"], unstacked_colors=["black"], unstacked_kwargs_list=[{"linestyle": "dotted"}], - xlabel=key, + xlabel="Observable", ylabel="Entries", model_sum_kwargs={"show": True, "label": "Model", "color": "navy"}, model_uncertainty_label="Stat. unc.", ) -add_text( - "Model made of histograms", - ax=ax, - loc="over left", -) +mh.add_text("Model made of histograms", ax=ax, loc="over left") # --8<-- [end:plot_body] # --8<-- [end:full_code] diff --git a/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py b/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py index 84abe4ac..900bb14e 100644 --- a/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py +++ b/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py @@ -7,60 +7,55 @@ # --8<-- [start:full_code] # --8<-- [start:imports] -from plothist_utils import get_dummy_data - -df = get_dummy_data() - -# Define the histograms - -key = "variable_1" -range = (-9, 12) -category = "category" - -# Define masks -data_mask = df[category] == 8 - -# Make histograms import hist -from hist import Hist - -axis = hist.axis.Regular(50, range[0], range[1]) -data_hist = Hist(axis, storage=hist.storage.Weight()) -data_hist.fill(df[key][data_mask]) - -# Define some random functions that will be used as model components with functions +import numpy as np from scipy.stats import norm +import mplhep as mh + +np.random.seed(42) # --8<-- [end:imports] # --8<-- [start: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 1000 * norm.pdf(x, loc=0.5, scale=3) + return 200 * _binwidth * norm.pdf(x, loc=5, scale=0.5) def f_background1(x): - return 1000 * norm.pdf(x, loc=-1.5, scale=4) + return 3500 * _binwidth * norm.pdf(x, loc=0, scale=2) def f_background2(x): - return 3000 * norm.pdf(x, loc=-1.8, scale=1.8) + return 2000 * _binwidth * norm.pdf(x, loc=-3, scale=1) # --8<-- [end:setup] # --8<-- [start:plot_body] -### -from mplhep import comp - -fig, ax_main, ax_comparison = comp.data_model( +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=key, + xlabel="Observable", ylabel="Entries", model_sum_kwargs={"show": True, "label": "Model", "color": "navy"}, comparison="pull", diff --git a/pyproject.toml b/pyproject.toml index 254c5b86..9fdb37d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,11 +51,11 @@ docs = [ "mkdocs-git-revision-date-localized-plugin", "mkdocs-git-committers-plugin-2", "mkdocstrings[python]>=0.20", + "griffe_inherited_docstrings", ] test = [ "boost_histogram", "hist", - "plothist_utils", "pytest-mock", "pytest-mpl", "pytest-xdist", diff --git a/tests/baseline/model_all_comparisons.png b/tests/baseline/model_all_comparisons.png index 3caefd29..3f713508 100644 Binary files a/tests/baseline/model_all_comparisons.png and b/tests/baseline/model_all_comparisons.png differ diff --git a/tests/baseline/model_all_comparisons_no_model_unc.png b/tests/baseline/model_all_comparisons_no_model_unc.png index ad25f8a9..8dc982fa 100644 Binary files a/tests/baseline/model_all_comparisons_no_model_unc.png and b/tests/baseline/model_all_comparisons_no_model_unc.png differ diff --git a/tests/baseline/model_examples_pull.png b/tests/baseline/model_examples_pull.png index 659091ed..0e680c5c 100644 Binary files a/tests/baseline/model_examples_pull.png and b/tests/baseline/model_examples_pull.png differ diff --git a/tests/baseline/model_examples_pull_no_model_unc.png b/tests/baseline/model_examples_pull_no_model_unc.png index a92714b3..c1e6e2c5 100644 Binary files a/tests/baseline/model_examples_pull_no_model_unc.png and b/tests/baseline/model_examples_pull_no_model_unc.png differ diff --git a/tests/baseline/model_examples_stacked.png b/tests/baseline/model_examples_stacked.png index 5ab1440b..f1537d0b 100644 Binary files a/tests/baseline/model_examples_stacked.png and b/tests/baseline/model_examples_stacked.png differ diff --git a/tests/baseline/model_examples_stacked_unstacked.png b/tests/baseline/model_examples_stacked_unstacked.png index d70ee29f..1ded2500 100644 Binary files a/tests/baseline/model_examples_stacked_unstacked.png and b/tests/baseline/model_examples_stacked_unstacked.png differ diff --git a/tests/baseline/model_examples_unstacked.png b/tests/baseline/model_examples_unstacked.png index 32cacf39..fc17a4bb 100644 Binary files a/tests/baseline/model_examples_unstacked.png and b/tests/baseline/model_examples_unstacked.png differ diff --git a/tests/baseline/model_with_stacked_and_unstacked_function_components.png b/tests/baseline/model_with_stacked_and_unstacked_function_components.png index 3a0bca7c..5e5945c2 100644 Binary files a/tests/baseline/model_with_stacked_and_unstacked_function_components.png and b/tests/baseline/model_with_stacked_and_unstacked_function_components.png differ diff --git a/tests/baseline/model_with_stacked_and_unstacked_histograms_components.png b/tests/baseline/model_with_stacked_and_unstacked_histograms_components.png index 0156e690..5c4c1552 100644 Binary files a/tests/baseline/model_with_stacked_and_unstacked_histograms_components.png and b/tests/baseline/model_with_stacked_and_unstacked_histograms_components.png differ diff --git a/tests/baseline/ratio_data_vs_model_with_stacked_and_unstacked_function_components.png b/tests/baseline/ratio_data_vs_model_with_stacked_and_unstacked_function_components.png index 8569113c..8353e0de 100644 Binary files a/tests/baseline/ratio_data_vs_model_with_stacked_and_unstacked_function_components.png and b/tests/baseline/ratio_data_vs_model_with_stacked_and_unstacked_function_components.png differ