def show_BF_ADF(self, imsize=(20, 10)): fontsize = int(np.amax(np.asarray(imsize))) plt.figure(figsize=imsize) plt.subplot(1, 2, 1) plt.imshow(self.data_adf) scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 0 scalebar.color = "w" plt.gca().add_artist(scalebar) plt.axis("off") at = mploff.AnchoredText("ADF-STEM", prop=dict(size=fontsize), frameon=True, loc="lower left") at.patch.set_boxstyle("round, pad=0., rounding_size=0.2") plt.gca().add_artist(at) plt.subplot(1, 2, 2) plt.imshow(np.sum(self.data_4D, axis=(-1, -2))) scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 0 scalebar.color = "w" plt.gca().add_artist(scalebar) plt.axis("off") at = mploff.AnchoredText("Summed 4D-STEM", prop=dict(size=fontsize), frameon=True, loc="lower left") at.patch.set_boxstyle("round, pad=0., rounding_size=0.2") plt.gca().add_artist(at) plt.tight_layout()
def pl_bf_synth_cl(N, gs, x_min_cmd, x_max_cmd, y_min_cmd, y_max_cmd, x_ax, y_ax, synth_clst, cp_r, shift_isoch): ''' Top tiers synthetic clusters obtained. ''' gs_map = { 1: gs[0:2, 0:2], 2: gs[0:2, 2:4], 3: gs[0:2, 4:6], 4: gs[0:2, 6:8], 5: gs[0:2, 8:10], 6: gs[2:4, 0:2], 7: gs[2:4, 2:4], 8: gs[2:4, 4:6], 9: gs[2:4, 6:8], 10: gs[2:4, 8:10] } ax = plt.subplot(gs_map.get(N)) #Set plot limits plt.xlim(x_min_cmd, x_max_cmd) plt.ylim(y_min_cmd, y_max_cmd) #Set axis labels plt.xlabel('$' + x_ax + '$', fontsize=18) plt.ylabel('$' + y_ax + '$', fontsize=18) # Set minor ticks ax.minorticks_on() ax.xaxis.set_major_locator(MultipleLocator(1.0)) ax.grid(b=True, which='major', color='gray', linestyle='--', lw=1) # Add text box text1 = '\n$N_{{synth}} = {}$\n'.format(len(synth_clst[0])) text2 = '$z = {}$\n'.format(cp_r[0]) text3 = '$log(age) = {}$\n'.format(cp_r[1]) text4 = '$E_{{(B-V)}} = {}$\n'.format(cp_r[2]) text5 = '$(m-M)_o = {}$\n'.format(cp_r[3]) text6 = '$M_{{\odot}} = {}$\n'.format(cp_r[4]) text7 = '$b_{{frac}} = {}$'.format(cp_r[5]) text = text1 + text2 + text3 + text4 + text5 + text6 + text7 ob = offsetbox.AnchoredText(text, pad=.2, loc=1, prop=dict(size=12)) ob.patch.set(alpha=0.6) ax.add_artist(ob) # Number of top tier. ob = offsetbox.AnchoredText('{}'.format(N), pad=0.2, loc=2, prop=dict(size=12)) ob.patch.set(alpha=0.85) ax.add_artist(ob) # Plot isochrone. plt.plot(shift_isoch[0], shift_isoch[1], 'r', lw=1.2) # Plot synth clust. plt.scatter(synth_clst[0], synth_clst[2], marker='o', s=40, c='#4682b4', lw=0.5)
def reliability_diagram(probabilities, labels, path="", bins=10, axis=None): ece, bin_aces, bin_accs, bin_confs = expected_calibration_error(probabilities, labels, bins=bins) if axis is None: text = offsetbox.AnchoredText( f"ECE: {(ece * 100):.2f}%\nAccuracy: {accuracy(probabilities, labels):.2f}%\nConfidence: {100 * confidence(probabilities):.2f}%", loc="upper left", frameon=False, prop=dict(fontsize=12)) fig, ax = plt.subplots(figsize=(9, 9), tight_layout=True) ax.add_artist(text) else: ax = axis ax.bar(x=np.arange(0, 1, 0.1), height=bin_accs, width=0.1, linewidth=1, edgecolor='black', align='edge', color='dodgerblue') ax.bar(x=np.arange(0, 1, 0.1), height=bin_aces, bottom=bin_accs, width=0.1, linewidth=1, edgecolor='crimson', align='edge', color='crimson', fill=False, hatch='/') ax.bar(x=np.arange(0, 1, 0.1), height=bin_aces, bottom=bin_accs, width=0.1, linewidth=1, edgecolor='crimson', align='edge', color='crimson', alpha=0.3) if axis is None: ax.set_ylim(0, 1) ax.set_xlim(0, 1) ax.plot(ax.get_xlim(), ax.get_ylim(), color='black', linestyle='dashed', linewidth=1.0) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.tick_params(direction='out', labelsize=12, right=False, top=False) ax.set_ylabel('Accuracy', fontsize=14) ax.set_xlabel('Confidence', fontsize=14) plt.savefig(path if path else 'reliability_diagram.pdf', format='pdf', dpi=1200) else: ax.tick_params(right=False, left=False, top=False, bottom=False, labelright=False, labelleft=False, labeltop=False, labelbottom=False) ax.set_frame_on(False)
def flCMD( ax, plot_style, x_min_cmd, x_max_cmd, y_min_cmd, y_max_cmd, x_ax, y_ax, N_fr, x_fr_rject, y_fr_rject, x_fr_accpt, y_fr_accpt, f_sz_pt, err_bar, col_idx): """ Field stars CMD diagram. """ # Set plot limits plt.xlim(x_min_cmd, x_max_cmd) plt.ylim(y_min_cmd, y_max_cmd) # Set axis labels plt.xlabel('$' + x_ax + '$') plt.ylabel('$' + y_ax + '$') if plot_style == 'asteca': ax.grid() # Plot accepted/rejected stars within the field regions defined. if x_fr_rject: plt.scatter(x_fr_rject, y_fr_rject, marker='x', c='teal', s=15, lw=.5, zorder=2) if x_fr_accpt: plt.scatter(x_fr_accpt, y_fr_accpt, marker='o', c='b', s=f_sz_pt, lw=0.3, edgecolor='k', zorder=3) n_field = int(len(x_fr_accpt) / float(N_fr)) # Add text box. text = r'$N_{{field}} \approx {}$'.format(n_field) ob = offsetbox.AnchoredText(text, pad=0.2, loc=1) ob.patch.set(alpha=0.7) ax.add_artist(ob) # If list is not empty, plot error bars at several values. x_val, mag_y, xy_err = err_bar if x_val: plt.errorbar( x_val, mag_y, yerr=xy_err[0], xerr=xy_err[col_idx], fmt='k.', lw=0.8, ms=0., zorder=4)
def clCMD( ax, plot_style, x_min_cmd, x_max_cmd, y_min_cmd, y_max_cmd, x_ax, y_ax, xr, yr, xa, ya, n_memb, cl_sz_pt, err_bar, col_idx): # Set plot limits plt.xlim(x_min_cmd, x_max_cmd) plt.ylim(y_min_cmd, y_max_cmd) # Set axis labels plt.xlabel('$' + x_ax + '$') plt.ylabel('$' + y_ax + '$') if plot_style == 'asteca': ax.grid() # Add text box. text = r'$N_{{memb}} \approx {}$'.format(n_memb) ob = offsetbox.AnchoredText(text, pad=0.2, loc=1) ob.patch.set(alpha=0.7) ax.add_artist(ob) # Plot stars in CMD. if yr: # Only attempt to plot if any star is stored in the list. plt.scatter(xr, yr, marker='x', c='teal', s=12, lw=.5, zorder=2) plt.scatter( xa, ya, marker='o', c='r', s=cl_sz_pt, lw=0.3, edgecolor='k', zorder=3) # If list is not empty, plot error bars at several values. x_val, mag_y, xy_err = err_bar if x_val: plt.errorbar( x_val, mag_y, yerr=xy_err[0], xerr=xy_err[col_idx], fmt='k.', lw=0.8, ms=0., zorder=4)
def pl_hist_g(gs, fig, asp_ratio, x_name, y_name, coord, cent_bin, clust_rad, bin_width, hist_2d_g): ''' 2D Gaussian convolved histogram. ''' bin_w_r = error_round.round_to_y(bin_width) ax = plt.subplot(gs[0:2, 2:4]) plt.xlabel('{} (bins)'.format(x_name), fontsize=12) plt.ylabel('{} (bins)'.format(y_name), fontsize=12) ax.minorticks_on() plt.axvline(x=cent_bin[0], linestyle='--', color='white') plt.axhline(y=cent_bin[1], linestyle='--', color='white') # Radius circle = plt.Circle((cent_bin[0], cent_bin[1]), clust_rad / bin_width, color='w', fill=False) fig.gca().add_artist(circle) # Add text box. text = 'Bin $\simeq$ {0:g} {1}'.format(bin_w_r, coord) ob = offsetbox.AnchoredText(text, pad=0.2, loc=1, prop=dict(size=10)) ob.patch.set(alpha=0.85) ax.add_artist(ob) plt.imshow(hist_2d_g.transpose(), origin='lower') # If RA is used, invert axis. if coord == 'deg': ax.invert_xaxis() ax.set_aspect(aspect=asp_ratio)
def plot_color_dpc(self, skip=2, portion=7, imsize=(20, 10)): fontsize = int(np.amax(np.asarray(imsize))) sc_font = {"weight": "bold", "size": fontsize} mpl.rc("font", **sc_font) cc = self.XComC + ((1j) * self.YComC) cc_color = st.util.cp_image_val(cc) cutter = 1 / portion cutstart = (np.round( np.asarray(self.XComC.shape) - (cutter * np.asarray(self.XComC.shape)))).astype(int) ypos, xpos = np.mgrid[0:self.YComC.shape[0], 0:self.XComC.shape[1]] ypos = ypos xcut = (xpos[cutstart[0]:self.XComC.shape[0], cutstart[1]:self.XComC.shape[1]] - cutstart[1]) ycut = (np.flipud(ypos[cutstart[0]:self.XComC.shape[0], cutstart[1]:self.XComC.shape[1]]) - cutstart[0]) dx = self.XComC[cutstart[0]:self.XComC.shape[0], cutstart[1]:self.XComC.shape[1]] dy = self.YComC[cutstart[0]:self.XComC.shape[0], cutstart[1]:self.XComC.shape[1]] cc_cut = cc_color[cutstart[0]:self.XComC.shape[0], cutstart[1]:self.XComC.shape[1], :] plt.figure(figsize=imsize) plt.subplot(1, 2, 1) plt.imshow(cc_color) scalebar = mpss.ScaleBar(self.calib, "pm") scalebar.location = "lower right" scalebar.box_alpha = 0 scalebar.color = "w" plt.gca().add_artist(scalebar) plt.axis("off") at = mploff.AnchoredText( "Center of Mass Shift", prop=dict(size=fontsize), frameon=True, loc="lower left", ) at.patch.set_boxstyle("round, pad=0., rounding_size=0.2") plt.gca().add_artist(at) plt.subplot(1, 2, 2) plt.imshow(cc_cut) plt.quiver( xcut[::skip, ::skip], ycut[::skip, ::skip], dx[::skip, ::skip], dy[::skip, ::skip], pivot="mid", color="w", ) scalebar = mpss.ScaleBar(self.calib, "pm") scalebar.location = "lower right" scalebar.box_alpha = 0 scalebar.color = "w" plt.gca().add_artist(scalebar) plt.axis("off") plt.tight_layout()
def plx_histo(gs, plot_style, plx_offset, plx_clrg, plx_x_kde, kde_pl, plx_flrg, flag_no_fl_regs_i): """ Histogram for the distribution of parallaxes within the cluster region. """ ax = plt.subplot(gs[0:2, 0:2]) ax.set_title('Offset applied: +{}'.format(plx_offset)) plt.xlabel('Plx [mas]') plt.ylabel('N') if plot_style == 'asteca': ax.grid() # Normalized histogram for cluster region. if len(plx_clrg) > 100: Nb = 100 elif 50 < len(plx_clrg) <= 100: Nb = 50 else: Nb = 25 h_cl, _, _ = plt.hist(plx_clrg, Nb, density=True, zorder=4, color='#9aafd1', alpha=0.75, label=r"Cluster region ($N_{fit}$)") # Plot histogram for the parallaxes of the field regions. if not flag_no_fl_regs_i: plt.hist(plx_flrg, 100, density=True, zorder=1, color='#ef703e', alpha=0.5, label="Field regions") plt.plot(plx_x_kde, kde_pl / (max(kde_pl) / max(h_cl)), color='b', lw=1., zorder=4) # Maximum KDE value. p_max_mas = plx_x_kde[np.argmax(kde_pl)] plt.axvline(x=p_max_mas, linestyle='--', color='b', lw=.7, zorder=5) plx_lt_zero = 100. * plx_clrg[plx_clrg < 0.].size / plx_clrg.size ob = offsetbox.AnchoredText( r"$Plx_{{max}}$={:.3f} [mas]".format(p_max_mas) + '\n' + r"$Plx<0 \rightarrow$ {:.1f}%".format(plx_lt_zero), pad=0.2, loc=1) ob.patch.set(alpha=0.85) ax.add_artist(ob) plt.xlim(max(-1., np.mean(plx_clrg) - 3. * np.std(plx_clrg)), min(3., np.mean(plx_clrg) + 3. * np.std(plx_clrg))) # Avoid showing the value 0.0 in the y axis. plt.ylim(0.01, plt.ylim()[1]) ax.legend(loc=7)
def show_potential(self, imsize=(15, 17)): """ Calculate the projected potential from the DPC measurements. This is accomplished by calculating the phase shift iteratively from the normalized center of mass shifts. Normalization means calculating COM shifts in inverse length units and then multiplying them with the electron wavelength to get an electron independent mrad shift, which is used to generate the phase. This phase is proportional to the projected potential for weak phase object materials (with *lots* of assumptions) """ fontsize = int(np.amax(np.asarray(imsize))) self.phase = st.dpc.integrate_dpc(self.XComC * self.wavelength, self.YComC * self.wavelength) self.potential = self.phase / self.sigma pm = np.amax(np.abs(self.potential)) * (10**10) plt.figure(figsize=imsize) fontsize = int(0.9 * np.max(imsize)) sc_font = {"weight": "bold", "size": fontsize} gs = mpgs.GridSpec(imsize[1], imsize[0]) ax1 = plt.subplot(gs[0:15, 0:15]) ax2 = plt.subplot(gs[15:17, :]) ax1.imshow(self.potential * (10**10), vmin=-pm, vmax=pm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax1.add_artist(scalebar) ax1.axis("off") at = mploff.AnchoredText( "Calculated projected potential from DPC phase", prop=dict(size=fontsize), frameon=True, loc="lower left", ) at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") ax1.add_artist(at) sb = np.zeros((10, 1000), dtype=np.float) for ii in range(10): sb[ii, :] = np.linspace(-pm, pm, 1000) ax2.imshow(sb, cmap="RdBu_r") ax2.yaxis.set_visible(False) no_labels = 7 x1 = np.linspace(0, 1000, no_labels) ax2.set_xticks(x1) ax2.set_xticklabels(np.round(np.linspace(-pm, pm, no_labels), 6)) for axis in ["top", "bottom", "left", "right"]: ax2.spines[axis].set_linewidth(2) ax2.spines[axis].set_color("black") ax2.xaxis.set_tick_params(width=2, length=6, direction="out", pad=10) ax2.set_title(r"Projected Potential (VÅ)", **sc_font) plt.tight_layout()
def pl_mp_histo(gs, n_memb_da, red_return, decont_algor_return): ''' Histogram for the distribution of membership probabilities from the decontamination algorithm. ''' memb_prob_avrg_sort, flag_decont_skip = decont_algor_return # Only attempt to plot if the DA was applied. if flag_decont_skip is False: # Reduced membership. red_memb_fit, min_prob = red_return[0], red_return[-1][0] ax = plt.subplot(gs[4:6, 2:4]) plt.xlim(0., 1.) plt.xlabel('MP (membership probability)', fontsize=12) plt.ylabel('N (normalized)', fontsize=12) ax.minorticks_on() ax.grid(b=True, which='major', color='gray', linestyle='--', lw=1) prob_data = [star[7] for star in memb_prob_avrg_sort] # Histogram of the data. n_bins = int((max(prob_data) - min(prob_data)) / 0.025) # Normalized histogram. weights = np.ones_like(prob_data) / len(prob_data) n, bins, patches = plt.hist(prob_data, n_bins, weights=weights, normed=0) # Get bin centers. bin_centers = 0.5 * (bins[:-1] + bins[1:]) # scale values to interval [0,1] col = bin_centers - min(bin_centers) col /= max(col) cm = plt.cm.get_cmap('RdYlBu_r') # Plot histo colored according to colormap. for c, p in zip(col, patches): plt.setp(p, 'facecolor', cm(c)) # Add text box. if g.rm_params[0] == 'mag': str_pm = ['mag', '\leq', 'mag'] else: str_pm = ['MP', '\geq', 'prob'] if g.rm_params[0] == 'local': str_pm.append(g.rm_params[0] + ';\,' + g.rm_params[1]) else: str_pm.append(g.rm_params[0].replace('_', '\_')) text1 = r'$n_{{memb-DA}}={}\,(MP \geq 0.5)$'.format(n_memb_da) text2 = r'${}_{{min}}={:.2f}\,({})$'.format(str_pm[2], min_prob, str_pm[3]) text3 = r'$N_{{fit}}={} \, ({} {} {}_{{min}})$'.format( len(red_memb_fit), str_pm[0], str_pm[1], str_pm[2]) text = text1 + '\n' + text2 + '\n' + text3 # Plot minimum probability line. plt.axvline(x=min_prob, linestyle='--', color='green', lw=2.5) ob = offsetbox.AnchoredText(text, loc=2, prop=dict(size=12)) ob.patch.set(boxstyle='square,pad=0.05', alpha=0.85) ax.add_artist(ob) # Avoid showing the value 0.0 in the y axis. plt.ylim(0.001, plt.ylim()[1])
def show_charge(self, imsize=(15, 17)): """ We calculate the charge from the corrected DPC center of mass datasets. This is done through Poisson's equation. """ fontsize = int(np.amax(np.asarray(imsize))) # Use Poisson's equation self.charge = ( ((np.gradient(self.e_fieldX)[1] + np.gradient(self.e_fieldY)[0]) * (self.calib * (10**(-12)))) * self.epsilon0 * 4 * np.pi) cm = np.amax(np.abs(self.charge)) plt.figure(figsize=imsize) fontsize = int(0.9 * np.max(imsize)) sc_font = {"weight": "bold", "size": fontsize} gs = mpgs.GridSpec(imsize[1], imsize[0]) ax1 = plt.subplot(gs[0:15, 0:15]) ax2 = plt.subplot(gs[15:17, :]) ax1.imshow(self.charge, vmin=-cm, vmax=cm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax1.add_artist(scalebar) ax1.axis("off") at = mploff.AnchoredText("Charge from DPC", prop=dict(size=fontsize), frameon=True, loc="lower left") at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") ax1.add_artist(at) sb = np.zeros((10, 1000), dtype=np.float) for ii in range(10): sb[ii, :] = np.linspace(cm / self.e_charge, -(cm / self.e_charge), 1000) ax2.imshow(sb, cmap="RdBu_r") ax2.yaxis.set_visible(False) no_labels = 7 x1 = np.linspace(0, 1000, no_labels) ax2.set_xticks(x1) ax2.set_xticklabels( np.round( np.linspace(cm / self.e_charge, -(cm / self.e_charge), no_labels), 6)) for axis in ["top", "bottom", "left", "right"]: ax2.spines[axis].set_linewidth(2) ax2.spines[axis].set_color("black") ax2.xaxis.set_tick_params(width=2, length=6, direction="out", pad=10) ax2.set_title(r"$\mathrm{Charge\: Density\: \left(e^{-} \right)}$", **sc_font) plt.tight_layout()
def pl_full_frame(gs, fig, project, x_offset, y_offset, x_name, y_name, coord, x_min, x_max, y_min, y_max, asp_ratio, kde_cent, x, y, st_sizes_arr, clust_rad): """ x,y finding chart of full frame """ ax = plt.subplot(gs[0:4, 0:4]) ax.set_aspect(aspect=asp_ratio) ax.set_title(r"$N_{{stars}}$={} (phot incomp)".format(len(x))) # Set plot limits plt.xlim(x_min, x_max) plt.ylim(y_min, y_max) # If RA is used, invert axis. if coord == 'deg': ax.invert_xaxis() # Set axis labels plt.xlabel('{} ({})'.format(x_name, coord)) plt.ylabel('{} ({})'.format(y_name, coord)) N_max = 50000 # HARDCODED if len(x) > N_max: print(" WARNING: too many stars. Plotting {} random samples.".format( N_max)) ids = np.random.choice(np.arange(len(x)), N_max, replace=False) x, y = x[ids], y[ids] # Plot stars. plt.scatter(x, y, marker='o', c='black', s=st_sizes_arr) # plt.axvline(x=kde_cent[0], linestyle='--', color='green') # plt.axhline(y=kde_cent[1], linestyle='--', color='green') plt.scatter(*kde_cent, marker='x', c='red', s=50) # Radius circle = plt.Circle((kde_cent[0], kde_cent[1]), clust_rad, color='red', fill=False) ax.add_artist(circle) # Add text box r_frmt = '{:.0f}' if coord == 'px' else '{:.5f}' if coord == 'deg' and project: x_cent = (kde_cent[0] / np.cos(np.deg2rad(kde_cent[1] + y_offset))) +\ x_offset else: x_cent = kde_cent[0] t1 = (r'${}_{{c}} =$' + r_frmt + r'$\,{}$').format(x_name, x_cent, coord) t2 = (r'${}_{{c}} =$' + r_frmt + r'$\,{}$').format(y_name, kde_cent[1] + y_offset, coord) text = t1 + '\n' + t2 ob = offsetbox.AnchoredText(text, pad=0.2, loc=2) ob.patch.set(alpha=0.85) ax.add_artist(ob)
def pl_cl_fl_regions(gs, fig, x_name, y_name, coord, x_min, x_max, y_min, y_max, asp_ratio, center_cl, clust_rad, field_regions, cl_region, flag_no_fl_regs): ''' Cluster and field regions defined. ''' ax = plt.subplot(gs[2:4, 0:2]) ax.set_aspect(aspect=asp_ratio) # Set plot limits plt.xlim(x_min, x_max) plt.ylim(y_min, y_max) # If RA is used, invert axis. if coord == 'deg': ax.invert_xaxis() # Set axis labels plt.xlabel('{} ({})'.format(x_name, coord), fontsize=12) plt.ylabel('{} ({})'.format(y_name, coord), fontsize=12) # Set minor ticks ax.minorticks_on() ax.grid(b=True, which='both', color='gray', linestyle='--', lw=0.5) # Radius circle = plt.Circle((center_cl[0], center_cl[1]), clust_rad, color='k', fill=False) fig.gca().add_artist(circle) # Add text box. text = 'Cluster + %d Field regions' % (len(field_regions)) ob = offsetbox.AnchoredText(text, pad=0.2, loc=1, prop=dict(size=12)) ob.patch.set(alpha=0.85) ax.add_artist(ob) # Plot cluster region. plt.scatter(zip(*cl_region)[1], zip(*cl_region)[2], marker='o', c='red', s=8, edgecolors='none') if not flag_no_fl_regs: # Plot field stars regions. col = cycle(['DimGray', 'ForestGreen', 'maroon', 'RoyalBlue']) for i, reg in enumerate(field_regions): stars_reg_temp = [[], []] for star in reg: # star[1] is the x coordinate and star[2] the y coordinate stars_reg_temp[0].append(star[1]) stars_reg_temp[1].append(star[2]) plt.scatter(stars_reg_temp[0], stars_reg_temp[1], marker='o', c=next(col), s=8, edgecolors='none')
def show_ADF_BF(self, imsize=(20, 10)): """ The ADF-STEM image is already loaded, while the `data_bf` attribute is obtained by summing up the 4D-STEM dataset along it's Fourier dimensions. This is also a great checkpoint to see whether the ADF-STEM and the BF-STEM images are the inverse of each other. """ self.data_bf = np.sum(self.data_4D, axis=(-1, -2)) fontsize = int(np.amax(np.asarray(imsize))) plt.figure(figsize=imsize) plt.subplot(1, 2, 1) plt.imshow(self.data_adf, cmap="inferno") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 0 scalebar.color = "w" plt.gca().add_artist(scalebar) plt.axis("off") at = mploff.AnchoredText("ADF-STEM", prop=dict(size=fontsize), frameon=True, loc="lower left") at.patch.set_boxstyle("round, pad=0., rounding_size=0.2") plt.gca().add_artist(at) plt.subplot(1, 2, 2) plt.imshow(self.data_bf, cmap="inferno") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 0 scalebar.color = "w" plt.gca().add_artist(scalebar) plt.axis("off") at = mploff.AnchoredText("Summed 4D-STEM", prop=dict(size=fontsize), frameon=True, loc="lower left") at.patch.set_boxstyle("round, pad=0., rounding_size=0.2") plt.gca().add_artist(at) plt.tight_layout()
def pl_ga_lkl(gs, l_min_max, lkl_old, model_done, new_bs_indx): ''' Likelihood evolution for the GA. ''' # Genetic algorithm parameters. N_b = g.bf_params[-1] n_pop, n_gen, fdif, p_cross, cr_sel, p_mut, n_el, n_ei, n_es = g.ga_params ax = plt.subplot(gs[6:8, 0:4]) plt.xlim(-0.5, len(lkl_old[0]) + int(0.01 * len(lkl_old[0]))) plt.ylim(l_min_max[0], l_min_max[1]) # Set minor ticks ax.minorticks_on() ax.tick_params(axis='y', which='major', labelsize=9) ax.grid(b=True, which='major', color='gray', linestyle='--', lw=0.6) plt.xlabel('Generation', fontsize=12) plt.ylabel('Likelihood', fontsize=12) # Add text box. text1 = '$N_{total} = %.2e\,;\,N_{btst} = %d$' '\n' % \ (len(model_done[0]), N_b) text2 = '$n_{gen}=%d\,;\,n_{pop}=%d$' '\n' % (n_gen, n_pop) text3 = '$f_{dif}=%0.2f\,;\,cr_{sel}=%s$' '\n' % (fdif, cr_sel) text4 = '$p_{cross}=%0.2f\,;\,p_{mut}=%0.2f$' '\n' % (p_cross, p_mut) text5 = '$n_{el}=%d\,;\,n_{ei}=%d\,;\,n_{es}=%d$' % (n_el, n_ei, n_es) text = text1 + text2 + text3 + text4 + text5 ob = offsetbox.AnchoredText(text, loc=1, prop=dict(size=12)) ob.patch.set(boxstyle='square,pad=0.', alpha=0.85) ax.add_artist(ob) # Plot likelihood minimum and mean lines. ax.plot(range(len(lkl_old[0])), lkl_old[0], lw=1., c='black', label='$L_{{min}}={:.1f}$'.format(min(lkl_old[0]))) ax.plot(range(len(lkl_old[0])), lkl_old[1], lw=1., c='blue', label='$L_{mean}$') # Plot line marking a new best solution found. for lin in new_bs_indx: lw_lin = 2. if lin > 0.05 * len(lkl_old[0]) else 0.5 plt.axvline(x=lin, linestyle='--', lw=lw_lin, color='green') # Legend. handles, labels = ax.get_legend_handles_labels() leg = ax.legend(handles, labels, loc='upper left', numpoints=1, fontsize=12) leg.get_frame().set_alpha(0.7)
def pl_GA_lkl(gs, pos, lkl_best, lkl_mean, OF_models, new_bs_indx, fit_diff, cross_prob, cross_sel, mut_prob, N_el, N_ei, N_es): """ Likelihood evolution for the GA. """ ax = plt.subplot(gs[pos[0]:pos[1], pos[2]:pos[3]]) # Set minor ticks ax.minorticks_on() ax.tick_params(axis='y', which='major', labelsize=xytickssize) ax.grid(b=True, which='major', color=grid_col, linestyle=grid_ls, lw=grid_lw) plt.xlabel('Generation', fontsize=xylabelsize) plt.ylabel('Likelihood', fontsize=xylabelsize) # Plot likelihood minimum and mean lines. ax.plot(range(len(lkl_best)), lkl_best, lw=1., c='green', label='$L_{{min}}={:.1f}$'.format(min(lkl_best))) ax.plot(range(len(lkl_best)), lkl_mean, lw=1., c='k', label='$L_{mean}$') ymin, ymax = ax.get_ylim() # Plot line marking a new best solution found. for lin in new_bs_indx: lw_lin = 1.5 if lin > 0.05 * len(lkl_best) else 0.5 plt.axvline(x=lin, linestyle='--', lw=lw_lin, color='blue') # Add text box. text1 = '$N_{{total}}={:.2E}$'.format(OF_models) text2 = '$f_{{dif}}={:.2f}\,;\,cr_{{sel}}={}$'.format(fit_diff, cross_sel) text3 = '$p_{{cross}}={:.2f}\,;\,p_{{mut}}={:.2f}$'.format( cross_prob, mut_prob) text4 = '$n_{{el}}={}\,;\,n_{{ei}}={}\,;\,n_{{es}}={}$'.format( N_el, N_ei, N_es) text = text1 + '\n' + text2 + '\n' + text3 + '\n' + text4 ob = offsetbox.AnchoredText(text, loc=1, prop=dict(size=legendsize)) ob.patch.set(boxstyle='square,pad=0.', alpha=0.85) ax.add_artist(ob) # Legend. handles, labels = ax.get_legend_handles_labels() leg = ax.legend(handles, labels, loc='upper left', numpoints=1, fontsize=legendsize) leg.get_frame().set_alpha(0.7) plt.xlim(-0.5, len(lkl_best) + int(0.01 * len(lkl_best))) plt.ylim(ymin, ymax)
def add_text_to_axis(gammas_gammalike, background_gammalike, best_prediction_cut, best_theta_square_cut, best_significance, e_low, e_high, ax): textstr = '\n'.join([ f'Significance: {best_significance:.2f}', f'Cuts: {best_theta_square_cut:.3f}, {best_prediction_cut:.3f}', f'Total Signal: {len(gammas_gammalike)}', f'Total Bkg: {len(background_gammalike)}', f'Energy Range {e_low:.3f}, {e_high:.3f}' ]) ob = offsetbox.AnchoredText(textstr, loc=1, prop={'fontsize': 7}) ob.patch.set_facecolor('lightgray') ob.patch.set_alpha(0.1) ax.add_artist(ob) ax.axvline(x=best_theta_square_cut, color='gray', lw=1, alpha=0.7)
def pl_densxy( N, gs, fig, asp_ratio, x_name, y_name, coord, bw_list, kde_pl, cent_xy): """ 2D Gaussian convolved histogram. """ gs_map = { 5: gs[0:2, 2:4], 6: gs[0:2, 4:6], 7: gs[0:2, 6:8], 8: gs[2:4, 2:4], 9: gs[2:4, 4:6], 10: gs[2:4, 6:8], 11: gs[4:6, 2:4], 12: gs[4:6, 4:6], 13: gs[4:6, 6:8], 14: gs[6:8, 2:4], 15: gs[6:8, 4:6], 16: gs[6:8, 6:8], 17: gs[8:10, 2:4], 18: gs[8:10, 4:6], 19: gs[8:10, 6:8] } ax = plt.subplot(gs_map.get(N)) if N in [5, 6, 7]: r_frmt = '{:.0f}' if coord == 'px' else '{:.4f}' plt.title(("Bandwidth: " + r_frmt + ' [{}]').format( bw_list[N - 5], coord), fontsize=11) plt.xlabel('{} ({})'.format(x_name, coord), fontsize=11) plt.ylabel('{} ({})'.format(y_name, coord), fontsize=11) plt.axvline(x=cent_xy[0], linestyle='--', lw=.85, color='green') plt.axhline(y=cent_xy[1], linestyle='--', lw=.85, color='green') plt.scatter(*cent_xy, marker='x', color='w', s=20) if kde_pl: ext_range, x, y, k_pos = kde_pl kde = np.reshape(k_pos.T, x.shape) plt.imshow( np.rot90(kde), cmap=plt.get_cmap('RdYlBu_r'), extent=ext_range) plt.contour(x, y, kde, colors='#551a8b', linewidths=0.5) # Add text box r_frmt = '{:.0f}' if coord == 'px' else '{:.3f}' t1 = ('${}_{{c}} =$' + r_frmt + '$\,{}$').format( x_name, cent_xy[0], coord) t2 = ('${}_{{c}} =$' + r_frmt + '$\,{}$').format( y_name, cent_xy[1], coord) text = t1 + '\n' + t2 ob = offsetbox.AnchoredText(text, pad=0.2, loc=2, prop=dict(size=10)) ob.patch.set(alpha=0.85) ax.add_artist(ob) # If RA is used, invert axis. if coord == 'deg': ax.invert_xaxis() ax.set_aspect(aspect=asp_ratio)
def pl_cl_diag(gs, x_min_cmd, x_max_cmd, y_min_cmd, y_max_cmd, x_ax, y_ax, stars_in_rjct, cl_region, n_memb, cl_sz_pt): ''' Cluster's stars diagram (stars inside cluster's radius) ''' ax = plt.subplot(gs[2:4, 6:8]) # Set plot limits plt.xlim(x_min_cmd, x_max_cmd) plt.ylim(y_min_cmd, y_max_cmd) # Set axis labels plt.xlabel('$' + x_ax + '$', fontsize=18) plt.ylabel('$' + y_ax + '$', fontsize=18) # Set minor ticks ax.minorticks_on() # Only draw units on axis (ie: 1, 2, 3) ax.xaxis.set_major_locator(MultipleLocator(1.0)) # Set grid ax.grid(b=True, which='major', color='gray', linestyle='--', lw=1, zorder=1) # Add text box. text1 = '$N_{{accpt}}={}\,(r \leq r_{{cl}})$'.format(len(cl_region)) text2 = r'$n_{{memb}} \approx {}$'.format(n_memb) text = text1 + '\n' + text2 ob = offsetbox.AnchoredText(text, pad=0.2, loc=1, prop=dict(size=12)) ob.patch.set(alpha=0.7) ax.add_artist(ob) # Plot stars in CMD. if len(stars_in_rjct) > 0: # Only attempt to plot if any star is stored in the list. plt.scatter(zip(*stars_in_rjct)[5], zip(*stars_in_rjct)[3], marker='x', c='teal', s=12, zorder=2) plt.scatter(zip(*cl_region)[5], zip(*cl_region)[3], marker='o', c='r', s=cl_sz_pt, lw=0.3, zorder=3)
def pl_fl_diag(gs, x_min_cmd, x_max_cmd, y_min_cmd, y_max_cmd, x_ax, y_ax, stars_f_rjct, stars_f_acpt, f_sz_pt): ''' Field stars CMD/CCD diagram. ''' ax = plt.subplot(gs[2:4, 4:6]) # Set plot limits plt.xlim(x_min_cmd, x_max_cmd) plt.ylim(y_min_cmd, y_max_cmd) # Set axis labels plt.xlabel('$' + x_ax + '$', fontsize=18) plt.ylabel('$' + y_ax + '$', fontsize=18) # Set minor ticks ax.minorticks_on() # Only draw units on axis (ie: 1, 2, 3) ax.xaxis.set_major_locator(MultipleLocator(1.0)) # Set grid ax.grid(b=True, which='major', color='gray', linestyle='--', lw=1, zorder=1) # Plot *all* rejected stars outside of the cluster region. plt.scatter(stars_f_rjct[0], stars_f_rjct[1], marker='x', c='teal', s=15, zorder=2) # Add text box. text = '$N_{{accpt}}={}\,(\star_{{field}})$'.format(len(stars_f_acpt[0])) ob = offsetbox.AnchoredText(text, pad=0.2, loc=1, prop=dict(size=12)) ob.patch.set(alpha=0.7) ax.add_artist(ob) # Plot accepted stars within the field regions defined, if at least one # exists. if stars_f_acpt[0]: plt.scatter(stars_f_acpt[0], stars_f_acpt[1], marker='o', c='b', s=f_sz_pt, lw=0.3, zorder=3)
def show_charge(self, imsize=(15, 15)): fontsize = int(np.amax(np.asarray(imsize))) XComV = self.XComC * self.wavelength * self.voltage YComV = self.YComC * self.wavelength * self.voltage self.charge = (-1) * ((np.gradient(XComV)[1] + np.gradient(YComV)[0]) / (self.calib * (10**(-12)))) cm = np.amax(np.abs(self.charge)) plt.figure(figsize=imsize) plt.imshow(self.charge, vmin=-cm, vmax=cm, cmap="seismic") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off") at = mploff.AnchoredText("Charge from DPC", prop=dict(size=fontsize), frameon=True, loc="lower left") at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") plt.gca().add_artist(at) plt.tight_layout()
def show_potential(self, imsize=(15, 15)): fontsize = int(np.amax(np.asarray(imsize))) XComV = self.XComC * self.wavelength * self.voltage YComV = self.YComC * self.wavelength * self.voltage self.pot = st.dpc.integrate_dpc(XComV, YComV) cm = np.amax(np.abs(self.pot)) plt.figure(figsize=imsize) plt.imshow(self.pot, vmin=-cm, vmax=cm, cmap="BrBG_r") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off") at = mploff.AnchoredText( "Measured potential", prop=dict(size=fontsize), frameon=True, loc="lower left", ) at.patch.set_boxstyle("round, pad=0., rounding_size=0.2") plt.gca().add_artist(at) plt.tight_layout()
def make_plot(minv, maxv, data, perc, avrg, e_avrg, id_tc): """ """ fig = plt.figure(figsize=(6, 6)) gs = gridspec.GridSpec(1, 1) print('Mean {} error in [{}, {}]: {}'.format(id_tc, minv, maxv, np.mean(zip(*data)[1]))) ax = plt.subplot(gs[0]) plt.xlabel(r'${}\, (mag)$'.format(id_tc)) plt.ylabel(r'$\sigma_{{{}}}\, (mag)$'.format(id_tc)) plt.xlim(minv, maxv) plt.ylim(-0.005, 0.5) plt.minorticks_on() plt.axhline(y=np.mean(zip(*data)[1]), lw=3, ls='--', color='r') plt.scatter(zip(*data)[0], zip(*data)[1], lw=0.5) # Average per 0.5 magnitude interval. plt.scatter(avrg, e_avrg, c='g', s=50) # for _ in np.arange(minv, maxv, 0.5): # Text box. text1 = r'$N={}$'.format(int(perc[0])) text2 = r'$\sigma_{{{}}}>0.1\;mag:\;{:.2f}\%$'.format( id_tc, perc[1] / perc[0] * 100.) text3 = r'$\overline{{\sigma_{{{}}}}}={:.4f}\;mag$'.format( id_tc, np.mean(zip(*data)[1])) text = text1 + '\n' + text2 + '\n' + text3 ob = offsetbox.AnchoredText(text, loc=9, prop=dict(size=12)) ob.patch.set(alpha=0.95) ax.add_artist(ob) # Output png file. fig.tight_layout() plt.savefig('{}_photom_errors.png'.format(id_tc), dpi=300, bbox_inches='tight')
def correct_dpc(self, imsize=(30, 15)): flips = np.zeros(4, dtype=bool) flips[2:4] = True chg_sums = np.zeros(4, dtype=self.XCom.dtype) angles = np.zeros(4, dtype=self.YCom.dtype) x0 = 90 for ii in range(2): to_flip = flips[2 * ii] if to_flip: xdpcf = np.flip(self.XCom) else: xdpcf = self.XCom rho_dpc, phi_dpc = st.dpc.cart2pol(self.XCom, self.YCom) x = sio.minimize(st.dpc.angle_fun, x0, args=(rho_dpc, phi_dpc)) min_x = x.x sol1 = min_x - 90 sol2 = min_x + 90 chg_sums[int(2 * ii)] = np.sum( st.dpc.charge_dpc(xdpcf, self.YCom, sol1) * self.data_adf) chg_sums[int(2 * ii + 1)] = np.sum( st.dpc.charge_dpc(xdpcf, self.YCom, sol2) * self.data_adf) angles[int(2 * ii)] = sol1 angles[int(2 * ii + 1)] = sol2 self.angle = (-1) * angles[chg_sums == np.amin(chg_sums)][0] self.final_flip = flips[chg_sums == np.amin(chg_sums)][0] if self.final_flip: xdpcf = np.fliplr(self.XCom) else: xdpcf = np.copy(self.XCom) rho_dpc, phi_dpc = st.dpc.cart2pol(xdpcf, self.YCom) self.XComC, self.YComC = st.dpc.pol2cart( rho_dpc, (phi_dpc - (self.angle * ((np.pi) / 180)))) vm = np.amax(np.abs(np.concatenate((self.XComC, self.YComC), axis=1))) fontsize = int(np.amax(np.asarray(imsize))) sc_font = {"weight": "bold", "size": fontsize} fig = plt.figure(figsize=imsize) gs = mpgs.GridSpec(1, 2) ax1 = plt.subplot(gs[0, 0]) ax2 = plt.subplot(gs[0, 1]) im = ax1.imshow(self.XComC, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax1.add_artist(scalebar) at = mploff.AnchoredText( "Corrected shift in X direction", prop=dict(size=fontsize), frameon=True, loc="upper left", ) at.patch.set_boxstyle("round, pad= 0., rounding_size= 0.2") ax1.add_artist(at) ax1.axis("off") im = ax2.imshow(self.YComC, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax2.add_artist(scalebar) at = mploff.AnchoredText( "Corrected shift in Y direction", prop=dict(size=fontsize), frameon=True, loc="upper left", ) at.patch.set_boxstyle("round, pad= 0., rounding_size= 0.2") ax2.add_artist(at) ax2.axis("off") p1 = ax1.get_position().get_points().flatten() p2 = ax2.get_position().get_points().flatten() ax_cbar = fig.add_axes([p1[0] - 0.075, -0.01, p2[2], 0.02]) cbar = plt.colorbar(im, cax=ax_cbar, orientation="horizontal") cbar.set_label(r"$\mathrm{Beam\: Shift\: \left(pm^{-1}\right)}$", **sc_font)
def pl_lkl_scatt(gs, ld_p, min_max_p, cp_r, cp_e, model_done): ''' Parameter likelihood scatter plot. ''' # Define parameters for upper and lower plots. if ld_p == '$z$': ax, cp, ci, zlab = plt.subplot(gs[8:10, 0:2]), 0, 1, '$log(age)$' plt.ylabel('Likelihood', fontsize=12) elif ld_p == '$log(age)$': ax, cp, ci, zlab = plt.subplot(gs[8:10, 2:4]), 1, 2, '$E_{{(B-V)}}$' elif ld_p == '$E_{{(B-V)}}$': ax, cp, ci, zlab = plt.subplot(gs[8:10, 4:6]), 2, 3, '$(m-M)_o$' elif ld_p == '$(m-M)_o$': ax, cp, ci, zlab = plt.subplot(gs[8:10, 6:8]), 3, 1, '$log(age)$' elif ld_p == '$M\,(M_{{\odot}})$': ax, cp, ci, zlab = plt.subplot(gs[8:10, 8:10]), 4, 5, '$b_{{frac}}$' elif ld_p == '$b_{{frac}}$': ax, cp, ci, zlab = plt.subplot(gs[8:10, 10:12]), 5, 4,\ '$M\,(M_{{\odot}})$' # Parameter values and errors. xp, e_xp = cp_r[0][cp], cp_e[cp] # Set x axis limit. xp_min, xp_max = min_max_p[cp] # Special axis ticks for metallicity. if ld_p == '$z$': z_xmin, z_step = min_max_p[-1] ax.xaxis.set_ticks(np.arange(z_xmin, xp_max, z_step)) plt.xlim(xp_min, xp_max) # Set minor ticks ax.minorticks_on() ax.tick_params(axis='y', which='major', labelsize=9) plt.xlabel(ld_p, fontsize=16) # Add textbox. text = (ld_p + '$ = {} \pm {}$').format(xp, e_xp) ob = offsetbox.AnchoredText(text, pad=0.1, loc=2, prop=dict(size=12)) ob.patch.set(alpha=0.8) ax.add_artist(ob) plt.axvline(x=xp, linestyle='--', color='red', zorder=2) # Plot scatter points over likelihood density map. cm = plt.cm.get_cmap('viridis') col_arr = [float(_) for _ in zip(*model_done[0])[ci]] SC = plt.scatter(zip(*model_done[0])[cp], model_done[1], marker='o', c=col_arr, s=25, edgecolors='k', lw=0.2, edgecolor='w', cmap=cm, zorder=3) if e_xp > 0.: # Plot error bars only if errors where assigned. plt.axvline(x=xp + e_xp, linestyle='--', color='blue') plt.axvline(x=xp - e_xp, linestyle='--', color='blue') # Set y axis limit. min_lik = min(model_done[1]) if min_lik > 0: min_y, max_y = min_lik - min_lik * 0.1, 2.5 * min_lik else: min_y, max_y = min_lik + min_lik * 0.1, -2.5 * min_lik plt.ylim(min_y, max_y) # Position colorbar. the_divider = make_axes_locatable(ax) color_axis = the_divider.append_axes("right", size="2%", pad=0.1) # Colorbar. cbar = plt.colorbar(SC, cax=color_axis) cbar.set_label(zlab, fontsize=12, labelpad=4) cbar.ax.tick_params(labelsize=8)
def pl_bf_synth_cl(gs, x_min_cmd, x_max_cmd, y_min_cmd, y_max_cmd, x_ax, y_ax, synth_clst, syn_b_edges, cp_r, cp_e, shift_isoch): ''' Best fit synthetic cluster obtained. ''' ax = plt.subplot(gs[4:6, 8:10]) # Set plot limits plt.xlim(x_min_cmd, x_max_cmd) plt.ylim(y_min_cmd, y_max_cmd) # Set axis labels plt.xlabel('$' + x_ax + '$', fontsize=18) plt.ylabel('$' + y_ax + '$', fontsize=18) # Set minor ticks ax.minorticks_on() ax.xaxis.set_major_locator(MultipleLocator(1.0)) # Plot grid. if g.bf_params[2] == 'dolphin': for x_ed in syn_b_edges[0]: # vertical lines ax.axvline(x_ed, linestyle=':', color='k', zorder=1) for y_ed in syn_b_edges[1]: # horizontal lines ax.axhline(y_ed, linestyle=':', color='k', zorder=1) # Add text box text = '$({};\,{})$'.format(g.bf_params[2], g.bf_params[3]) ob = offsetbox.AnchoredText(text, pad=.2, loc=1, prop=dict(size=12)) ob.patch.set(alpha=0.85) ax.add_artist(ob) else: ax.grid(b=True, which='major', color='gray', linestyle='--', lw=1, zorder=1) if synth_clst.any(): # Plot synthetic cluster. plt.scatter(synth_clst[0], synth_clst[2], marker='o', s=40, c='#4682b4', lw=0.5, zorder=4) text1 = '$N_{{synth}} = {}$'.format(len(synth_clst[0])) else: text1 = '$N_{{synth}} = {}$'.format(0) # Add text box ob = offsetbox.AnchoredText(text1, pad=.2, loc=2, prop=dict(size=14)) ob.patch.set(alpha=0.85) ax.add_artist(ob) # Plot isochrone. plt.plot(shift_isoch[0], shift_isoch[1], 'r', lw=1.2) # Add text box to the right of the synthetic cluster. ax_t = plt.subplot(gs[4:6, 10:12]) ax_t.axis('off') # Remove axis from frame. # Map isochrones set selection to proper name. iso_print = g.tracks_dict.get(g.ps_params[2]) t1 = r'$Synthetic\;cluster\;parameters$' + '\n' + \ r'$[Tracks:\;{}]$'.format(iso_print.replace(' ', '\;')) + '\n\n' t2 = r'$z\qquad\; =\, {} \pm {}$'.format(cp_r[0], cp_e[0]) + '\n' t3 = r'$log(age)\, =\, {} \pm {}$'.format(cp_r[1], cp_e[1]) + '\n' t4 = r'$E_{{(B-V)}}\;\,=\, {} \pm {}$'.format(cp_r[2], cp_e[2]) + '\n' t5 = r'$(m-M)_o = {} \pm {}$'.format(cp_r[3], cp_e[3]) + '\n' t6 = r'$M\,(M_{{\odot}})\quad\;=\,{} \pm {}$'.format(cp_r[4], cp_e[4]) + '\n' t7 = r'$b_{{frac}}\quad\,\, =\, {} \pm {}$'.format(cp_r[5], cp_e[5]) + '\n' text = t1 + t2 + t3 + t4 + t5 + t6 + t7 ob = offsetbox.AnchoredText(text, pad=1, loc=6, prop=dict(size=13)) ob.patch.set(alpha=0.85) ax_t.add_artist(ob)
def entropy_hist(inclass, outclass, bins=100, norm=True, log=False, kde=False, jsd=False, path="", axis=None, label=""): """Makes a predictive entropy histogram or density plot for in- and out-of-domain data. Args: inclass (Numpy array): The predicted probabilities of the in-domain data. outclass (Numpy array): The predicted probabilities of the out-of-domain data. bins (int, optional): The number of bins to use for the histogram. Default: 100. norm (bool, optional): If True, entropy values are normalized between 0 and 1. log (bool, optional): If True, the x-axis is shown in log-scale. Default: False. kde (bool, optional): If True, plots a density instead of a histogram. Default: True. jsd (bool, optional): If True, calculates and prints the symmetric, discretized Kullback-Leibler divergence. path (string, optional): Where to save the figure. Default: Current directory. axis (matplotlib.Axis, optional): If provided, plots the figure on this axis. """ if axis is None: fig, ax = plt.subplots(figsize=(9, 9), tight_layout=True) else: ax = axis inclass_entropy = predictive_entropy(inclass) outclass_entropy = predictive_entropy(outclass) xlim = np.log(inclass.shape[1]) if norm: inclass_entropy /= xlim outclass_entropy /= xlim xlim = 1 bins = np.linspace(0, xlim, num=bins) kwargs = dict(hist_kws={'alpha': .5}, kde_kws={'linewidth': 3}) if kde: ax = distplot(inclass_entropy, color='dodgerblue', label=label if label else 'In Class', bins=bins, hist=False, ax=ax, **kwargs) ax = distplot(outclass_entropy, color='crimson', label='Out of Class', bins=bins, hist=False, ax=ax, **kwargs) l1 = ax.lines[0] l2 = ax.lines[1] x1 = l1.get_xydata()[:, 0] y1 = l1.get_xydata()[:, 1] x2 = l2.get_xydata()[:, 0] y2 = l2.get_xydata()[:, 1] ax.fill_between(x1, y1, color="dodgerblue", alpha=0.5) ax.fill_between(x2, y2, color="crimson", alpha=0.5) ax.set_ylim(0.0, ax.get_ylim()[1]) ax.set_ylabel('Density', fontsize=18) else: kwargs['hist_kws']['histtype'] = 'stepfilled' kwargs['hist_kws']['edgecolor'] = 'black' distplot(inclass_entropy, color='dodgerblue', label=label if label else 'In Class', bins=bins, hist=True, kde=False, ax=ax, **kwargs) distplot(outclass_entropy, color='crimson', label='Out of Class', bins=bins, hist=True, kde=False, ax=ax, **kwargs) ax.set_ylabel('Frequency', fontsize=20) ax.set_xlim(0, xlim) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.tick_params(direction='out', labelsize=18, right=False, top=False) ax.legend(fontsize=20, loc='upper right', frameon=False) ax.set_xlabel('Entropy', fontsize=20) if log: ax.set_xscale('log') if not kde: ax.set_xlim(np.min(bins), np.max(bins)) if jsd: jsd = binned_kl_distance(inclass, outclass) text = offsetbox.AnchoredText(f"JSD: {jsd:.3f}", loc="upper center", frameon=True, prop=dict(fontsize=20)) ax.add_artist(text) if axis is None: plt.savefig(path if path else "entropy_hist.pdf", format='pdf', dpi=1200)
def initial_dpc(self, imsize=(30, 15)): qq, pp = np.mgrid[0:self.data_4D.shape[-1], 0:self.data_4D.shape[-2]] yy, xx = np.mgrid[0:self.data_4D.shape[0], 0:self.data_4D.shape[1]] yy = np.ravel(yy) xx = np.ravel(xx) self.YCom = np.empty(self.data_4D.shape[0:2], dtype=np.float) self.XCom = np.empty(self.data_4D.shape[0:2], dtype=np.float) for ii in range(len(yy)): pattern = self.data_4D[yy[ii], xx[ii], :, :] self.YCom[yy[ii], xx[ii]] = self.inverse * ( (np.sum(np.multiply(qq, pattern)) / np.sum(pattern)) - self.beam_y) self.XCom[yy[ii], xx[ii]] = self.inverse * ( (np.sum(np.multiply(pp, pattern)) / np.sum(pattern)) - self.beam_x) vm = np.amax(np.abs(np.concatenate((self.XCom, self.YCom), axis=1))) fontsize = int(np.amax(np.asarray(imsize))) sc_font = {"weight": "bold", "size": fontsize} fig = plt.figure(figsize=imsize) gs = mpgs.GridSpec(1, 2) ax1 = plt.subplot(gs[0, 0]) ax2 = plt.subplot(gs[0, 1]) im = ax1.imshow(self.XCom, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax1.add_artist(scalebar) at = mploff.AnchoredText( "Shift in X direction", prop=dict(size=fontsize), frameon=True, loc="upper left", ) at.patch.set_boxstyle("round, pad= 0., rounding_size= 0.2") ax1.add_artist(at) ax1.axis("off") im = ax2.imshow(self.YCom, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib / 1000, "nm") scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax2.add_artist(scalebar) at = mploff.AnchoredText( "Shift in Y direction", prop=dict(size=fontsize), frameon=True, loc="upper left", ) at.patch.set_boxstyle("round, pad= 0., rounding_size= 0.2") ax2.add_artist(at) ax2.axis("off") p1 = ax1.get_position().get_points().flatten() p2 = ax2.get_position().get_points().flatten() ax_cbar = fig.add_axes([p1[0] - 0.075, -0.01, p2[2], 0.02]) cbar = plt.colorbar(im, cax=ax_cbar, orientation="horizontal") cbar.set_label(r"$\mathrm{Beam\: Shift\: \left(pm^{-1}\right)}$", **sc_font)
def pl_phot_err(gs, colors, filters, id_kinem, mags, em_float, cl_region_c, cl_region_rjct_c, stars_out_c, stars_out_rjct_c, N_st_err_rjct, err_bar_all): """ Photometric + kinematic error rejection. """ # Main magnitude (x) data for accepted/rejected stars. mmag_out_acpt, mmag_out_rjct, mmag_in_acpt, mmag_in_rjct =\ np.array([]), np.array([]), np.array([]), np.array([]) if stars_out_c: mmag_out_acpt = np.array(list(zip(*list(zip(*stars_out_c))[3]))[0]) if stars_out_rjct_c: mmag_out_rjct = np.array( list(zip(*list(zip(*stars_out_rjct_c))[3]))[0]) if cl_region_c: mmag_in_acpt = np.array(list(zip(*list(zip(*cl_region_c))[3]))[0]) if cl_region_rjct_c: mmag_in_rjct = np.array(list(zip(*list(zip(*cl_region_rjct_c))[3]))[0]) # Define parameters for main magnitude error plot. y_ax, x_ax = prep_plots.ax_names(filters[0], filters[0], 'mag') # Remove parenthesis y_ax = y_ax.replace('(', '').replace(')', '') err_plot = [[x_ax, y_ax, 4, 0]] # For all defined colors. for i, _ in enumerate(colors): y_ax, _ = prep_plots.ax_names(colors[i], filters[0], 'mag') err_plot.append([x_ax, y_ax, 6, i]) pd_Plx, pd_PMRA, pd_PMDE, pd_RV = id_kinem[0], id_kinem[2], id_kinem[4],\ id_kinem[6] # For the kinematic data if pd_Plx != 'n': err_plot.append([x_ax, "Plx", 8, 0]) if pd_PMRA != 'n': err_plot.append([x_ax, "PMra", 8, 1]) if pd_PMDE != 'n': err_plot.append([x_ax, "PMde", 8, 2]) if pd_RV != 'n': err_plot.append([x_ax, "RV", 8, 3]) # Set plot limits x_min, x_max = min(mags[0]) - 0.5, max(mags[0]) + 0.5 for i, pl in enumerate(err_plot): x_ax, y_ax, j, k = pl ax = plt.subplot(gs[i // 2:(i // 2) + 1, 3 * (i % 2):3 * (i % 2) + 3]) plt.xlim(x_min, x_max) # Set axis labels plt.xlabel(r'$' + x_ax + r'$') plt.ylabel(r'$\sigma_{{{}}}$'.format(y_ax)) ax.set_facecolor('#EFF0F1') # Rejected stars outside the cluster region if any(mmag_out_rjct) and any(stars_out_rjct_c): starsPlot('rjct', mmag_out_rjct, list(zip(*list(zip(*stars_out_rjct_c))[j]))[k]) if any(mmag_in_rjct) and any(cl_region_rjct_c): # Rejected stars inside the cluster region starsPlot('rjct', mmag_in_rjct, list(zip(*list(zip(*cl_region_rjct_c))[j]))[k]) if any(mmag_in_acpt) and any(cl_region_c): # Accepted stars inside the cluster region. starsPlot('accpt_in', mmag_in_acpt, list(zip(*list(zip(*cl_region_c))[j]))[k]) if any(mmag_out_acpt) and any(stars_out_c): # Accepted stars outside the cluster region. starsPlot('accpt_out', mmag_out_acpt, list(zip(*list(zip(*stars_out_c))[j]))[k]) if j == 4: # Plot legend in the main magnitude plot. leg = plt.legend(fancybox=True, loc='upper left', scatterpoints=1, markerscale=2.) # Set the alpha value of the legend. leg.get_frame().set_alpha(0.7) # Max error cut max_cut_y = em_float[0] ax.hlines(y=max_cut_y, xmin=x_min, xmax=x_max, color='k', linestyles='dashed', zorder=4) txt = r"$max={}$ mag".format(em_float[0]) txt += "\n" + r"$N_{{rjct}}={}$".format(N_st_err_rjct[0]) ob = offsetbox.AnchoredText(txt, loc=1) ob.patch.set(alpha=0.7) ax.add_artist(ob) # Plot error curve plt.plot(err_bar_all[1], err_bar_all[2][0], color='yellow', ls='--', lw=2, zorder=5) elif j == 6: max_cut_y = em_float[1 + k] ax.hlines(y=max_cut_y, xmin=x_min, xmax=x_max, color='k', linestyles='dashed', zorder=4) txt = r"$max={}$ mag".format(em_float[1 + k]) txt += "\n" + r"$N_{{rjct}}={}$".format(N_st_err_rjct[1][k]) ob = offsetbox.AnchoredText(txt, loc=2) ob.patch.set(alpha=0.7) ax.add_artist(ob) plt.plot(err_bar_all[1], err_bar_all[2][k + 1], color='yellow', ls='--', lw=2, zorder=5) else: unit = '[mas]' if k == 0 else '[mas/yr]' # Use single PM max error value defined, for PMde k = 1 if k == 2 else 1 max_cut_y = em_float[-(3 - k)] ax.hlines(y=max_cut_y, xmin=x_min, xmax=x_max, color='k', linestyles='dashed', zorder=4) txt = r"$max={}$ {}".format(em_float[-(3 - k)], unit) txt += "\n" + r"$N_{{rjct}}={}$".format(N_st_err_rjct[2][k]) ob = offsetbox.AnchoredText(txt, loc=2) ob.patch.set(alpha=0.7) ax.add_artist(ob) # Maximum error limit of 1. plt.ylim(-0.0024, min(plt.ylim()[1], 2. * max_cut_y, 1.))
def plot_color_dpc(self, start_frac=0, size_frac=1, skip=2, imsize=(20, 10)): """ Use this to plot the corrected DPC center of mass shifts. If no variables are passed, the arrows are overlaid on the entire image. Parameters ---------- start_frac: float, optional The starting fraction of the image, where you will cut from to show the overlaid arrows. Default is 0 stop_frac: float, optional The ending fraction of the image, where you will cut from to show the overlaid arrows. Default is 1 """ fontsize = int(np.amax(np.asarray(imsize))) sc_font = {"weight": "bold", "size": fontsize} mpl.rc("font", **sc_font) cc = self.XComC + ((1j) * self.YComC) cc_color = st.util.cp_image_val(cc) cutstart = (np.asarray(self.XComC.shape) * start_frac).astype(int) cut_stop = (np.asarray(self.XComC.shape) * (start_frac + size_frac)).astype(int) ypos, xpos = np.mgrid[0:self.YComC.shape[0], 0:self.XComC.shape[1]] ypos = ypos xcut = xpos[cutstart[0]:cut_stop[0], cutstart[1]:cut_stop[1]] ycut = np.flipud(ypos[cutstart[0]:cut_stop[0], cutstart[1]:cut_stop[1]]) dx = self.XComC[cutstart[0]:cut_stop[0], cutstart[1]:cut_stop[1]] dy = self.YComC[cutstart[0]:cut_stop[0], cutstart[1]:cut_stop[1]] cc_cut = cc_color[cutstart[0]:cut_stop[0], cutstart[1]:cut_stop[1]] overlay = mpl.patches.Rectangle( cutstart[0:2], cut_stop[0] - cutstart[0], cut_stop[1] - cutstart[1], linewidth=1.5, edgecolor="w", facecolor="none", ) plt.figure(figsize=imsize) plt.subplot(1, 2, 1) plt.imshow(cc_color) scalebar = mpss.ScaleBar(self.calib, "pm") scalebar.location = "lower right" scalebar.box_alpha = 0 scalebar.color = "w" plt.gca().add_artist(scalebar) plt.axis("off") at = mploff.AnchoredText( "Center of Mass Shift", prop=dict(size=fontsize), frameon=True, loc="lower left", ) at.patch.set_boxstyle("round, pad=0., rounding_size=0.2") plt.gca().add_artist(at) plt.gca().add_patch(overlay) plt.subplot(1, 2, 2) plt.imshow(cc_cut) plt.quiver( xcut[::skip, ::skip] - cutstart[1], ycut[::skip, ::skip] - cutstart[0], dx[::skip, ::skip], dy[::skip, ::skip], pivot="mid", color="w", ) scalebar = mpss.ScaleBar(self.calib, "pm") scalebar.location = "lower right" scalebar.box_alpha = 0 scalebar.color = "w" plt.gca().add_artist(scalebar) plt.axis("off") plt.tight_layout()