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)
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))
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)
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)
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)))