示例#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 get_auto_ylims(ax: plt.axis,
                   hMC,
                   *,
                   hdata=None,
                   log_y=False,
                   yaxis_scale='auto'
                   ) -> Tuple[Union[int, float], Union[int, float]]:
    """Return the minimum and maximum values for the y axis. If yaxis_scale is 'auto', get a value such that the
    histogram stays in bounds of the plot, and the legend does not overlap with the histogram.

    """

    ylims = ax.get_ylim()
    ymin = ylims[0]

    if yaxis_scale == 'auto':
        if not isinstance(hMC[0], float):
            hMC = hMC[-1]

        labelFraction = 1 / 4
        legendFraction = 1 / 3

        maxBelowLabel = max(hMC[:len(hMC) * 2 // 3])
        maxBelowLegend = max(hMC[len(hMC) * 2 // 3:])
        if hdata is not None:
            maxBelowLabel = max(maxBelowLabel,
                                max(hdata[:len(hdata) * 2 // 3]))
            maxBelowLegend = max(maxBelowLegend,
                                 max(hdata[len(hdata) * 2 // 3:]))

        if log_y:
            ymax = max(maxBelowLabel**(1 / (1 - labelFraction)),
                       maxBelowLegend**(1 / (1 - legendFraction)))
        else:
            ymax = max(maxBelowLabel / (1 - labelFraction),
                       maxBelowLegend / (1 - legendFraction))
    else:
        if log_y:
            ymax = ylims[1]**yaxis_scale
        else:
            ymax = ylims[1] * yaxis_scale

    return ymin, ymax
def set_inset_spectrum(axis: plt.axis, data: np.ndarray, current_index: int,
                       peak_collection: PeakCollection) -> plt.axis:
    axis.plot(data)  # Show intensity spectrum
    axis = plot_peaks(axis=axis, collection=peak_collection)  # Show peaks
    y_bot, y_top = axis.get_ylim()
    text_height = y_bot + 0.6 * (y_top - y_bot)  # Data coordinates
    _margin = 50
    x_lim = [
        max(0, current_index - _margin),
        min(len(data) - 1, current_index + _margin)
    ]
    # Plot clusters
    # for cluster in peak_collection.get_clusters:
    #     bound_left, bound_right = cluster.get_value_slice
    #     if bound_right > x_lim[0] or bound_left < x_lim[1]:
    #         axis.axvspan(bound_left, bound_right, alpha=0.5, color='green')
    #     if x_lim[0] < cluster.get_avg_x < x_lim[1]:
    #         axis.text(x=cluster.get_avg_x, y=text_height, s=r'$\tilde{m}$'+f'={cluster.get_transverse_mode_id}')
    axis.axvline(x=current_index, color='r')
    axis.set_xlim(x_lim)
    return axis
示例#4
0
    def plot_on(self,
                ax: plt.axis,
                ylabel="Events",
                draw_legend=True,
                legend_inside=True,
                hide_labels: bool = False):
        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

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

        if not hide_labels:
            ax.set_xlabel(self._variable.x_label, plot_style.xlabel_pos)
            y_label = self._get_y_label(False, bin_width, ylabel)
            ax.set_ylabel(y_label, plot_style.ylabel_pos)
        if draw_legend:
            if legend_inside:
                ax.legend(frameon=False)
                ylims = ax.get_ylim()
                ax.set_ylim(ylims[0], 1.4 * ylims[1])

            else:
                ax.legend(frameon=False, bbox_to_anchor=(1, 1))

        return ax
示例#5
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)
示例#6
0
    def plot_on(self,
                ax: plt.axis,
                draw_legend: bool = True,
                legend_inside: bool = True,
                yaxis_scale=1.3,
                normed: bool = False,
                ylabel="Events",
                hide_labels: bool = False) -> plt.axis:
        """
        Plots the component on a given matplotlib.pyplot.axis

        :param ax: matplotlib.pyplot.axis where the histograms will be drawn
        on.
        :param draw_legend: Draw legend on axis if True.
        :param normed: If true the histograms are normalized.

        :return: matplotlib.pyplot.axis with histogram drawn on it
        """
        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

        for component in self._mc_components['single']:
            if component.histtype == 'stepfilled':
                alpha = 0.6
                edge_color = 'black'
            else:
                edge_color = None
                alpha = 1.0
            ax.hist(x=component.data,
                    bins=bin_edges,
                    density=normed,
                    weights=component.weights,
                    histtype=component.histtype,
                    label=component.label,
                    edgecolor=edge_color
                    if edge_color is not None else component.color,
                    alpha=alpha,
                    lw=1.5,
                    ls=component.ls,
                    color=component.color)

        if not hide_labels:
            ax.set_xlabel(self._variable.x_label, plot_style.xlabel_pos)

            y_label = self._get_y_label(normed=normed,
                                        bin_width=bin_width,
                                        evts_or_cand=ylabel)
            ax.set_ylabel(y_label, plot_style.ylabel_pos)

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

        return ax