Exemple #1
0
    def draw_errorbars(self):
        if self.n_data_sets == 1:
            bin_height = [self.bin_content]
            bin_err = [self.bin_err]
            if self.histtype != 'marker':
                vis_object = [self.vis_object]
            else:
                vis_object = self.vis_object
        elif self.stacked:
            bin_height = [self.bin_content[-1]]
            bin_err = [self.bin_err]
            vis_object = [self.vis_object]
        else:
            bin_height = self.bin_content
            bin_err = self.bin_err
            vis_object = self.vis_object

        if not self.stacked:
            n_data_sets_eff = self.n_data_sets
        else:
            n_data_sets_eff = 1
        for i in range(n_data_sets_eff):
            if self.err_dict['err_color'] == 'auto' and not self.stacked:
                if self.histtype == 'marker':
                    err_color = colors.to_rgba(vis_object[i]._get_rgba_face())
                elif self.histtype in ['stepfilled', 'bar']:
                    err_color = colors.to_rgba(
                        vis_object[i][0].get_facecolor())
                elif self.histtype == 'step':
                    err_color = colors.to_rgba(
                        vis_object[i][0].get_edgecolor())

                hls_tmp = colorsys.rgb_to_hls(*err_color[:-1])
                err_color = list(colorsys.hls_to_rgb(hls_tmp[0], hls_tmp[1]*0.7, hls_tmp[2])) + \
                    [err_color[-1]]
            elif self.err_dict['err_color'] == 'auto' and self.stacked:
                err_color = next(self.ax._get_lines.prop_cycler)['color']
            else:
                err_color = self.err_dict['err_color']

            if self.histtype == 'marker':
                if self.err_dict['err_x']:
                    xerr = self.widths * 0.5
                else:
                    xerr = None
                _, caps, _ = self.ax.errorbar(self.bin_centers,
                                              bin_height[i],
                                              linestyle='',
                                              marker='',
                                              yerr=bin_err[i],
                                              xerr=xerr,
                                              linewidth=2,
                                              color=err_color)
            else:
                if self.err_dict['err_style'] == 'line':
                    self.ax.errorbar(self.bin_centers,
                                     bin_height[i],
                                     linestyle='',
                                     marker='',
                                     yerr=bin_err[i],
                                     linewidth=2,
                                     color=err_color)

                elif self.err_dict['err_style'] == 'band':
                    if self.err_dict['err_type'] == 'poisson':
                        fill_between_steps(self.ax,
                                           self.bin_edges,
                                           bin_height[i] + bin_err[i][1],
                                           bin_height[i] - bin_err[i][0],
                                           step_where='pre',
                                           linewidth=0,
                                           color=err_color,
                                           alpha=self.hist_dict['alpha'] * 0.8,
                                           zorder=10)
                    else:
                        fill_between_steps(self.ax,
                                           self.bin_edges,
                                           bin_height[i] + bin_err[i],
                                           bin_height[i] - bin_err[i],
                                           step_where='pre',
                                           linewidth=0,
                                           color=err_color,
                                           alpha=self.hist_dict['alpha'] * 0.8,
                                           zorder=10)

                    if self.stacked:
                        poly_patch = self.vis_object[-1][0].get_xy()
                        self.ax.add_patch(
                            Polygon(poly_patch[:(len(poly_patch) + 1) // 2],
                                    closed=False,
                                    facecolor='none',
                                    edgecolor='k',
                                    linewidth=1,
                                    alpha=0.5,
                                    zorder=0))
Exemple #2
0
    def ratio_plot(hist_dict1,
                   hist_dict2,
                   bins=None,
                   range=None,
                   ratio_range=None,
                   err_style='band',
                   err_color='dimgray',
                   ratio_mode='default',
                   grid=False,
                   unity_line='red',
                   logx=False):
        '''Function for creating ratio plots (comparing two histograms by dividing their bin content).
        The call structure is very similar to producing two individual histograms, with additional
        arguments specifying the nature of the ratio plot.  The number of bins and ranges for both
        histograms must be equal.

        Note:
            Addition documentation soon.'''

        bin_range = range
        del range

        bins, bin_range = _check_args_ratio(hist_dict1, hist_dict2, bins,
                                            bin_range)
        hist_dict1['bins'] = bins
        hist_dict1['range'] = bin_range

        fig = plt.figure()
        gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1])
        ax1 = fig.add_subplot(gs[0])
        if logx:
            ax1.set_xscale("log", nonposx='clip')
        ax2 = fig.add_subplot(gs[1], sharex=ax1)
        # ax1.grid(True)
        # ax2.grid(True)
        plt.setp(ax1.get_xticklabels(), visible=False)
        fig.subplots_adjust(hspace=0.001)

        hist_dict1['ax'] = ax1
        hist_dict2['ax'] = ax1

        hist_con1 = HistContainer(**hist_dict1)
        bin_edges = hist_con1.bin_edges
        bin_range = (bin_edges[0], bin_edges[-1])
        hist_dict2['bins'] = bin_edges
        hist_dict2['range'] = bin_range
        hist_con2 = HistContainer(**hist_dict2)
        ax1.set_xlim(bin_range)

        if hist_con1.stacked:
            bc1 = hist_con1.bin_content[-1]
        else:
            bc1 = hist_con1.bin_content
        if hist_con2.stacked:
            bc2 = hist_con2.bin_content[-1]
        else:
            bc2 = hist_con2.bin_content

        berr1 = getattr(hist_con1, 'bin_err', np.zeros(len(bc1)))
        berr2 = getattr(hist_con2, 'bin_err', np.zeros(len(bc2)))

        ratio = bc1 / bc2
        ratio_err = ratio * np.sqrt((berr1 / bc1)**2 + (berr2 / bc2)**2)
        ratio_err_hi = ratio + ratio_err
        ratio_err_low = ratio - ratio_err

        ratio[ratio == 0] = np.nan

        fill_between_steps(ax2,
                           hist_con1.bin_edges,
                           ratio_err_hi,
                           ratio_err_low,
                           step_where='pre',
                           linewidth=0,
                           color=err_color,
                           alpha=0.2,
                           zorder=10)

        ax2.errorbar(hist_con1.bin_centers,
                     ratio,
                     yerr=None,
                     xerr=[
                         hist_con1.bin_centers - hist_con1.bin_edges[0:-1],
                         hist_con1.bin_edges[1:] - hist_con1.bin_centers
                     ],
                     fmt='d',
                     color=err_color)

        if unity_line:
            ax2.axhline(1, linewidth=3, color=unity_line, zorder=0)
        ax2.yaxis.set_major_locator(MaxNLocator(nbins=4, prune='upper'))
        if ratio_range:
            ax2.set_ylim(ratio_range)
        else:
            ax2.set_ylim((0, 2.0))

        return (ax1, ax2), (hist_con1.bin_content, hist_con1.bin_edges, hist_con1.vis_object), \
            (hist_con2.bin_content, hist_con2.bin_edges, hist_con2.vis_object)