Spaces:
Runtime error
Runtime error
| from typing import List, Tuple | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| from matplotlib.figure import Figure | |
| def hist_n_particles(q: List[int], label: str) -> Figure: | |
| """Generate histogram for particle counts on events. | |
| :param q: Count per event. | |
| :type q: List[int] | |
| :param label: Plot title. | |
| :type label: str | |
| :return: Figure with histogram and histogram ratio. | |
| :rtype: Figure | |
| """ | |
| fig, ax = plt.subplots(nrows=1, figsize=(15, 8)) | |
| bins, edges = np.histogram(q, bins=15, range=(0, 15)) | |
| for idx, val in enumerate(bins[::-1]): | |
| if val > 0: | |
| max_idx = len(bins) - idx - 1 | |
| edges = edges[:max_idx] | |
| bins = bins[:max_idx] | |
| break | |
| ax.bar(edges, bins, width=1, alpha=0.6) | |
| ax.set_title(label, fontsize=20, y=1.04) | |
| ax.set_xticks(edges) | |
| return fig | |
| def hist_var(q: List[float], ax: plt.Axes, **kwargs) -> plt.Axes: | |
| """Create histogram with error bars. | |
| :param q: Values to create histogram. | |
| :type q: List[float] | |
| :param ax: Axes in which histrogram is plotted. | |
| :type ax: plt.Axes | |
| :return: Axes with histogram. | |
| :rtype: plt.Axes | |
| """ | |
| bins, edges, _ = ax.hist( | |
| q, alpha=0.6, histtype="step", align="left", linewidth=4, **kwargs | |
| ) | |
| errors = np.sqrt(bins) | |
| bin_width = edges[1] - edges[0] | |
| ax.bar( | |
| x=edges[:-1], | |
| bottom=bins, | |
| height=errors, | |
| width=bin_width, | |
| alpha=0.0, | |
| color="w", | |
| hatch="/", | |
| ) | |
| ax.bar( | |
| x=edges[:-1], | |
| bottom=bins, | |
| height=-errors, | |
| width=bin_width, | |
| alpha=0.0, | |
| color="w", | |
| hatch="/", | |
| ) | |
| return ax | |
| def ratio_hist( | |
| processes_q: List[List[float]], | |
| hist_labels: List[str], | |
| reference_label: str, | |
| n_bins: int, | |
| hist_range: Tuple[int, int], | |
| title: str, | |
| figsize=(15, 8), | |
| ) -> Figure: | |
| """Generate histrograms with ratio pad | |
| :param processes_q: Quantity for each event and process | |
| :type processes_q: List[List[float]] | |
| :param hist_labels: Labels for each process | |
| :type hist_labels: List[str] | |
| :param reference_label: Label of process taken as the denominator of ratios | |
| :type reference_label: str | |
| :param n_bins: Number of bins for histograms | |
| :type n_bins: int | |
| :param hist_range: Range for histogram bins | |
| :type hist_range: Tuple[int] | |
| :param title: Plot title | |
| :type title: str | |
| :param figsize: Figure size for output plot | |
| :type figsize: Tuple[int] | |
| :return: Figure with histogram and histogram ratio. | |
| :rtype: Figure | |
| """ | |
| fig, ax = plt.subplots( | |
| nrows=len(processes_q), | |
| ncols=1, | |
| gridspec_kw={"height_ratios": [3] + [1] * (len(processes_q) - 1)}, | |
| sharex=True, | |
| figsize=figsize, | |
| ) | |
| legends = [] | |
| p_bins = {} | |
| p_edges = {} | |
| p_errors = {} | |
| edges = None | |
| for p, label in zip(processes_q, hist_labels): | |
| bins = n_bins | |
| if edges is not None: | |
| bins = edges | |
| bins, edges, _ = ax[0].hist( | |
| x=p, | |
| bins=bins, | |
| range=hist_range, | |
| fill=False, | |
| label=label, | |
| align="left", | |
| histtype="step", | |
| linewidth=4, | |
| ) | |
| p_bins[label] = bins | |
| p_edges[label] = edges | |
| p_errors[label] = np.sqrt(bins) | |
| legends += [label] | |
| bin_width = edges[1] - edges[0] | |
| for label in hist_labels: | |
| ax[0].bar( | |
| x=p_edges[label][:-1], | |
| bottom=p_bins[label], | |
| height=p_errors[label], | |
| width=bin_width, | |
| alpha=0.0, | |
| color="w", | |
| hatch="/", | |
| ) | |
| ax[0].bar( | |
| x=p_edges[label][:-1], | |
| bottom=p_bins[label], | |
| height=-p_errors[label], | |
| width=bin_width, | |
| alpha=0.0, | |
| color="w", | |
| hatch="/", | |
| ) | |
| legends += ["_", "_"] | |
| ax[0].set_ylabel("Events", fontsize=15) | |
| ax[0].set_title(title, fontsize=20) | |
| legends[-1] = "Stat. Uncertainty" | |
| ax[0].legend(legends) | |
| plot_idx = 1 | |
| ref_bins = p_bins[reference_label] | |
| ref_edges = p_edges[reference_label] | |
| ref_frac_error = p_errors[reference_label] / ref_bins | |
| for label in hist_labels: | |
| if label == reference_label: | |
| continue | |
| ratios = p_bins[label] / ref_bins | |
| error_ratio = ratios * (ref_frac_error + p_errors[label] / p_bins[label]) | |
| ax[plot_idx].bar( | |
| bottom=1.0, | |
| height=error_ratio, | |
| x=ref_edges[:-1], | |
| width=bin_width, | |
| alpha=0.3, | |
| color="blue", | |
| ) | |
| ax[plot_idx].bar( | |
| bottom=1.0, | |
| height=-error_ratio, | |
| x=ref_edges[:-1], | |
| width=bin_width, | |
| alpha=0.3, | |
| color="blue", | |
| ) | |
| ax[plot_idx].scatter(ref_edges[:-1], ratios, marker="o", color="black") | |
| ax[plot_idx].set_ylabel(f"{label}/{reference_label}") | |
| plot_idx += 1 | |
| return fig | |