예제 #1
0
    def plot_on(
        self,
        ax: plt.axis,
        draw_legend: bool = True,
        legend_inside: bool = True,
        legend_kwargs: dict = {},
        yaxis_scale=1.3,
        hide_labels: bool = False,
    ) -> plt.axis:

        for component in self.components:
            if component.style == 'point':
                ax.errorbar(
                    component.data.x_values,
                    component.data.y_values,
                    yerr=component.data.y_errors,
                    xerr=component.data.x_errors,
                    label=component.label,
                    color=component.color,
                    ls=component.ls,
                    marker=component.marker,
                )
            elif component.style == 'box':
                ax.bar(component.data.x_values,
                       2 * component.data.y_errors,
                       width=2 * component.data.x_errors,
                       bottom=component.data.y_values -
                       component.data.y_errors,
                       label=component.label,
                       color=component.color,
                       alpha=0.5)
            else:
                raise NotImplementedError(
                    "Options: point|box. If you require a new kind of plot, report a feature request"
                )

        if not hide_labels:
            ax.set_xlabel(self.variable.x_label, plot_style.xlabel_pos)
            ax.set_ylabel(self.variable.y_label, plot_style.ylabel_pos)

        if draw_legend:
            if legend_inside:
                ax.legend(frameon=False, **legend_kwargs)
                ylims = ax.get_ylim()
                ax.set_ylim(ylims[0], yaxis_scale * ylims[1])
            else:
                ax.legend(frameon=False,
                          bbox_to_anchor=(1, 1),
                          **legend_kwargs)

        return ax
예제 #2
0
    def plot_on(
        self,
        ax1: plt.axis,
        ax2,
        style="stacked",
        ylabel="Events",
        sum_color=plot_style.KITColors.kit_purple,
        draw_legend: bool = True,
        legend_inside: bool = True,
    ):
        bin_edges, bin_mids, bin_width = self._get_bin_edges()

        self._bin_edges = bin_edges
        self._bin_mids = bin_mids
        self._bin_width = bin_width

        sum_w = np.sum(np.array([
            binned_statistic(comp.data,
                             comp.weights,
                             statistic="sum",
                             bins=bin_edges)[0]
            for comp in self._mc_components["MC"]
        ]),
                       axis=0)

        sum_w2 = np.sum(np.array([
            binned_statistic(comp.data,
                             comp.weights**2,
                             statistic="sum",
                             bins=bin_edges)[0]
            for comp in self._mc_components["MC"]
        ]),
                        axis=0)

        hdata, _ = np.histogram(self._data_component.data, bins=bin_edges)

        if style.lower() == "stacked":
            ax1.hist(
                x=[comp.data for comp in self._mc_components['MC']],
                bins=bin_edges,
                weights=[comp.weights for comp in self._mc_components['MC']],
                stacked=True,
                edgecolor="black",
                lw=0.3,
                color=[comp.color for comp in self._mc_components['MC']],
                label=[comp.label for comp in self._mc_components['MC']],
                histtype='stepfilled')

            ax1.bar(x=bin_mids,
                    height=2 * np.sqrt(sum_w2),
                    width=self.bin_width,
                    bottom=sum_w - np.sqrt(sum_w2),
                    color="black",
                    hatch="///////",
                    fill=False,
                    lw=0,
                    label="MC stat. unc.")

        if style.lower() == "summed":
            ax1.bar(x=bin_mids,
                    height=2 * np.sqrt(sum_w2),
                    width=self.bin_width,
                    bottom=sum_w - np.sqrt(sum_w2),
                    color=sum_color,
                    lw=0,
                    label="MC")

        ax1.errorbar(x=bin_mids,
                     y=hdata,
                     yerr=np.sqrt(hdata),
                     ls="",
                     marker=".",
                     color="black",
                     label=self._data_component.label)

        y_label = self._get_y_label(False, bin_width, evts_or_cand=ylabel)
        # ax1.legend(loc=0, bbox_to_anchor=(1,1))
        ax1.set_ylabel(y_label, plot_style.ylabel_pos)

        if draw_legend:
            if legend_inside:
                ax1.legend(frameon=False)
                ylims = ax1.get_ylim()
                ax1.set_ylim(ylims[0], 1.4 * ylims[1])
            else:
                ax1.legend(frameon=False, bbox_to_anchor=(1, 1))

        ax2.set_ylabel(r"$\frac{\mathrm{Data - MC}}{\mathrm{Data}}$")
        ax2.set_xlabel(self._variable.x_label, plot_style.xlabel_pos)
        ax2.set_ylim((-1, 1))

        try:
            uhdata = unp.uarray(hdata, np.sqrt(hdata))
            uhmc = unp.uarray(sum_w, np.sqrt(sum_w2))
            ratio = (uhdata - uhmc) / uhdata

            ax2.axhline(y=0, color=plot_style.KITColors.dark_grey, alpha=0.8)
            ax2.errorbar(bin_mids,
                         unp.nominal_values(ratio),
                         yerr=unp.std_devs(ratio),
                         ls="",
                         marker=".",
                         color=plot_style.KITColors.kit_black)
        except ZeroDivisionError:
            ax2.axhline(y=0, color=plot_style.KITColors.dark_grey, alpha=0.8)

        plt.subplots_adjust(hspace=0.08)