Example #1
0
 def plot_1d_projection(self, map, plot_axis, **kwargs):
     """plot map projected on plot_axis"""
     r_vmin = kwargs.pop('r_vmin', None)
     r_vmax = kwargs.pop('r_vmax', None)
     axis = plt.gca()
     plt_binning = map.binning[plot_axis]
     hist = self.project_1d(map, plot_axis)
     if map.tex == 'data':
         axis.errorbar(plt_binning.weighted_centers.m,
                       unp.nominal_values(hist),
                       yerr=unp.std_devs(hist),
                       fmt='o',
                       markersize='4',
                       label=tex_dollars(text2tex('data')),
                       color='k',
                       ecolor='k',
                       mec='k',
                       **kwargs)
     else:
         axis.hist(inf2finite(plt_binning.weighted_centers.m),
                   weights=unp.nominal_values(hist),
                   bins=inf2finite(plt_binning.bin_edges.m),
                   histtype='step',
                   lw=1.5,
                   label=tex_dollars(text2tex(map.tex)),
                   color=self.color,
                   **kwargs)
         axis.bar(plt_binning.bin_edges.m[:-1],
                  2 * unp.std_devs(hist),
                  bottom=unp.nominal_values(hist) - unp.std_devs(hist),
                  width=plt_binning.bin_widths.m,
                  alpha=0.25,
                  linewidth=0,
                  color=self.color,
                  **kwargs)
     axis.set_xlabel(tex_dollars(plt_binning.label))
     if self.label:
         axis.set_ylabel(tex_dollars(text2tex(self.label)))
     if plt_binning.is_log:
         axis.set_xscale('log')
     if self.log:
         axis.set_yscale('log')
     else:
         axis.set_ylim(0, np.max(unp.nominal_values(hist)) * 1.4)
     axis.set_xlim(
         inf2finite(plt_binning.bin_edges.m)[0],
         inf2finite(plt_binning.bin_edges.m)[-1])
     if self.grid:
         plt.grid(True, which="both", ls='-', alpha=0.2)
Example #2
0
    def add_stamp(self, text=None, **kwargs):
        """Add common stamp with text.

        NOTE add_stamp cannot be used on a subplot that has been de-selected
        and then re-selected. It will write over existing text.

        """
        if self.stamp != '':
            stamp = tex_join('\n', self.stamp, text)
        else:
            stamp = text
        if self.loc == 'inside':
            a_text = AnchoredText(tex_dollars(stamp), loc=2, frameon=False,
                                  **kwargs)
            plt.gca().add_artist(a_text)
        elif self.loc == 'outside':
            plt.gca().set_title(tex_dollars(stamp))
Example #3
0
    def plot_xsec(self, map_set, ylim=None, logx=True):
        from pisa.utils import fileio

        zero_np_element = np.array([0])
        for map in map_set:
            binning = map.binning
            if 'true_energy' in binning.names:
                energy_binning = binning.true_energy
            elif 'reco_energy' in binning.names:
                energy_binning = binning.reco_energy
            else:
                dim_idx = binning.index('energy', use_basenames=True)
                energy_binning = binning.dims[dim_idx]

            fig = plt.figure(figsize=self.size)
            fig.suptitle(map.name, y=0.95)
            ax = fig.add_subplot(111)
            ax.grid(b=True, which='major')
            ax.grid(b=True, which='minor', linestyle=':')
            plt.xlabel(tex_dollars(energy_binning.label), size=18)
            plt.ylabel(tex_dollars(text2tex(self.label)), size=18)
            if self.log:
                ax.set_yscale('log')
            if logx:
                ax.set_xscale('log')
            if ylim:
                ax.set_ylim(ylim)
            ax.set_xlim(np.min(energy_binning.bin_edges.m),
                        np.max(energy_binning.bin_edges.m))

            hist = map.hist
            array_element = np.hstack((hist, zero_np_element))
            ax.step(energy_binning.bin_edges.m, array_element, where='post')

            fileio.mkdir(self.outdir)
            fig.savefig(self.outdir + '/' + map.name + '.png',
                        bbox_inches='tight',
                        dpi=150)
Example #4
0
    def plot_1d_ratio(self, maps, plot_axis, **kwargs):
        """make a ratio plot for a 1d projection"""
        r_vmin = kwargs.pop('r_vmin', None)
        r_vmax = kwargs.pop('r_vmax', None)
        axis = plt.gca()
        map0 = maps[0]
        plt_binning = map0.binning[plot_axis]
        hist = self.project_1d(map0, plot_axis)
        hist0 = unp.nominal_values(hist)
        # TODO: should this be used somewhere?
        err0 = unp.std_devs(hist)

        axis.set_xlim(
            inf2finite(plt_binning.bin_edges.m)[0],
            inf2finite(plt_binning.bin_edges.m)[-1])
        maximum = 1.0
        minimum = 1.0
        self.reset_colors()
        for map in maps:
            self.next_color()
            hist = self.project_1d(map, plot_axis)
            hist1 = unp.nominal_values(hist)
            err1 = unp.std_devs(hist)
            ratio = np.zeros_like(hist0)
            ratio_error = np.zeros_like(hist0)
            for i, hist0i in enumerate(hist0):
                if hist1[i] == 0 and hist0i == 0:
                    ratio[i] = 1.
                    ratio_error[i] = 1.
                elif hist1[i] != 0 and hist0i == 0:
                    logging.warning('deviding non 0 by 0 for ratio')
                    ratio[i] = 0.
                    ratio_error[i] = 1.
                else:
                    ratio[i] = hist1[i] / hist0i
                    ratio_error[i] = err1[i] / hist0i
                    minimum = min(minimum, ratio[i])
                    maximum = max(maximum, ratio[i])

            if map.tex == 'data':
                axis.errorbar(plt_binning.weighted_centers.m,
                              ratio,
                              yerr=ratio_error,
                              fmt='o',
                              markersize='4',
                              label=tex_dollars(text2tex('data')),
                              color='k',
                              ecolor='k',
                              mec='k')
            else:
                _ = axis.hist(inf2finite(plt_binning.weighted_centers.m),
                              weights=ratio,
                              bins=inf2finite(plt_binning.bin_edges.m),
                              histtype='step',
                              lw=1.5,
                              label=tex_dollars(text2tex(map.tex)),
                              color=self.color)

                axis.bar(plt_binning.bin_edges.m[:-1],
                         2 * ratio_error,
                         bottom=ratio - ratio_error,
                         width=plt_binning.bin_widths.m,
                         alpha=0.25,
                         linewidth=0,
                         color=self.color)

        if self.grid:
            plt.grid(True, which="both", ls='-', alpha=0.2)
        self.fig.subplots_adjust(hspace=0)
        axis.set_ylabel(tex_dollars(text2tex('ratio')))
        axis.set_xlabel(tex_dollars(plt_binning.label))
        # Calculate nice scale:
        if r_vmin is not None and r_vmax is not None:
            axis.set_ylim(1 - r_vmin, 1 + r_vmax)
        else:
            off = max(maximum - 1, 1 - minimum)
            axis.set_ylim(1 - 1.2 * off, 1 + 1.2 * off)
Example #5
0
    def plot_2d_map(self, map, cmap=None, **kwargs):
        """plot map or transform on current axis in 2d"""
        vmin = kwargs.pop('vmin', None)
        vmax = kwargs.pop('vmax', None)
        axis = plt.gca()

        if isinstance(map, BinnedTensorTransform):
            binning = map.input_binning
        elif isinstance(map, Map):
            binning = map.binning
        else:
            raise TypeError('Unhandled `map` type %s' % map.__class__.__name__)

        dims = binning.dims
        bin_centers = binning.weighted_centers
        bin_edges = binning.bin_edges
        linlog = all([(d.is_log or d.is_lin) for d in binning])

        zmap = map.nominal_values
        if self.log:
            zmap = np.log10(zmap)

        if self.symmetric:
            vmax = np.max(np.abs(np.ma.masked_invalid(zmap)))
            vmin = -vmax
            if cmap is None:
                cmap = CMAP_DIV
        else:
            if vmax is None:
                vmax = np.max(zmap[np.isfinite(zmap)])
            if vmin is None:
                vmin = np.min(zmap[np.isfinite(zmap)])
            if cmap is None:
                cmap = CMAP_SEQ
        extent = [
            np.min(bin_edges[0].m),
            np.max(bin_edges[0].m),
            np.min(bin_edges[1].m),
            np.max(bin_edges[1].m)
        ]

        # Only lin or log can be handled by imshow...otherise use colormesh

        # TODO: fix imshow for log-scaled energy vs. lin-scaled coszen, or
        # remove this code altogether
        if False:  #linlog:
            # Needs to be transposed for imshow
            _ = plt.imshow(zmap.T,
                           origin='lower',
                           interpolation='nearest',
                           extent=extent,
                           aspect='auto',
                           cmap=cmap,
                           vmin=vmin,
                           vmax=vmax,
                           **kwargs)
        else:
            x, y = np.meshgrid(bin_edges[0], bin_edges[1])
            pcol = plt.pcolormesh(x,
                                  y,
                                  np.ma.masked_invalid(zmap.T),
                                  vmin=vmin,
                                  vmax=vmax,
                                  cmap=cmap,
                                  linewidth=0,
                                  rasterized=True,
                                  **kwargs)
            pcol.set_edgecolor('face')

        if self.annotate:
            for i in range(len(bin_centers[0])):
                for j in range(len(bin_centers[1])):
                    bin_x = bin_centers[0][i].m
                    bin_y = bin_centers[1][j].m
                    plt.annotate('%.1f' % (zmap[i, j]),
                                 xy=(bin_x, bin_y),
                                 xycoords=('data', 'data'),
                                 xytext=(bin_x, bin_y),
                                 textcoords='data',
                                 va='top',
                                 ha='center',
                                 size=7)

        axis.set_xlabel(tex_dollars(dims[0].label))
        axis.set_ylabel(tex_dollars(dims[1].label))
        axis.set_xlim(extent[0:2])
        axis.set_ylim(extent[2:4])

        # TODO: use log2 scale & integer tick labels if too few major gridlines
        # result from default log10 scale
        if dims[0].is_log:
            axis.set_xscale('log')
        if dims[1].is_log:
            axis.set_yscale('log')

        if self.log:
            col_bar = plt.colorbar(format=r'$10^{%.1f}$')
        else:
            col_bar = plt.colorbar()

        if self.label:
            col_bar.set_label(tex_dollars(text2tex(self.label)))