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 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 plotRxDConcentration(speciesLabel, regionLabel, plane='xy', fontSize=12, showFig=True): from .. import sim # set font size plt.rcParams.update({'font.size': fontSize}) species = sim.net.rxd['species'][speciesLabel]['hObj'] region = sim.net.rxd['regions'][regionLabel]['hObj'] fig = plt.figure(figsize=(4, 10)) plane2mean = {'xz': 1, 'xy': 2} plt.imshow(species[region].states3d[:].mean(plane2mean[plane]).T, interpolation='nearest', origin='upper') # extent=k[extracellular].extent('xy') sb = scalebar.ScaleBar(1e-6) sb.location = 'lower left' ax = plt.gca() ax.xaxis.set_visible(False) ax.yaxis.set_visible(False) plt.xlabel(plane[0]) plt.ylabel(plane[1]) ax.add_artist(sb) plt.colorbar(label="$%s^+$ (mM)" % (species.name)) # show fig if showFig: _showFigure() return fig, {'data': species[region].states3d[:].mean(plane2mean[plane])}
def peaks_vis(self, dist, thresh, imsize=(15, 15), spot_color="c"): if not self.reference_check: self.ref_reg = np.ones_like(self.image, dtype=bool) pixel_dist = dist / self.calib self.threshold = thresh self.data_thresh = ((self.image * self.ref_reg) - self.threshold) / ( 1 - self.threshold ) self.data_thresh[self.data_thresh < 0] = 0 data_peaks = skfeat.peak_local_max( self.data_thresh, min_distance=int(pixel_dist / 3), indices=False ) peak_labels = scnd.measurements.label(data_peaks)[0] merged_peaks = scnd.measurements.center_of_mass( data_peaks, peak_labels, range(1, np.max(peak_labels) + 1) ) peaks = np.array(merged_peaks) self.peaks = (st.afit.remove_close_vals(peaks, pixel_dist)).astype(np.float) spot_size = int(0.5 * np.mean(np.asarray(imsize))) plt.figure(figsize=imsize) plt.imshow(self.image) plt.scatter(self.peaks[:, 1], self.peaks[:, 0], c=spot_color, s=spot_size) scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off") self.peaks_check = True
def get_cbed(self, imsize=(15, 15), show_image=False): """ We calculate the mean CBED pattern by averaging the Fourier data, to get the object attribute `cbed`. We fit this with a circle function to obtain the object attributes: `beam_x`: x-coordinates of the circle `beam_y`: y-coordinates of the circle `beam_r`: radius of the circle We use the calculated radius and the known aperture size to get the Fourier space calibration, which is stored as the `inverse` attribute """ self.cbed = np.mean(self.data_4D, axis=(0, 1)) self.beam_x, self.beam_y, self.beam_r = st.util.sobel_circle(self.cbed) self.inverse = self.aperture / (self.beam_r * self.wavelength) if show_image: plt.figure(figsize=imsize) plt.imshow(self.cbed, cmap="inferno") scalebar = mpss.ScaleBar(self.inverse, "1/m", mpss.SI_LENGTH_RECIPROCAL) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off")
def add_scale_bar(ax, downsample=None, plane=None): """Adds a scale bar to the plot. Uses the x resolution value and assumes that it is in microns per pixel. The bar's color is taken from the setting in :attr:``config.process_settings``. Args: ax: The plot that will show the bar. downsample: Downsampling factor by which the resolution will be multiplied; defaults to None. plane: Plane of the image, used to transpose the resolutions to find the corresponding x resolution for the given orientation. Defaults to None. """ # ensure that ScaleBar package exists if not scalebar: return resolutions = config.resolutions[0] if plane: # transpose resolutions to the given plane _, arrs_1d = transpose_images(plane, arrs_1d=[resolutions]) resolutions = arrs_1d[0] res = resolutions[2] # assume scale bar is along x-axis if downsample: res *= downsample scale_bar = scalebar.ScaleBar(res, u'\u00b5m', scalebar.SI_LENGTH, box_alpha=0, color=config.roi_profile["scale_bar_color"], location=3) ax.add_artist(scale_bar)
def show_image(self, gaussval=0, imsize=(15, 15), colormap="inferno"): """ Parameters ---------- gaussval: int, optional Extent of Gaussian blurring in pixels to generate a background image for subtraction. Default is 0 imsize: tuple, optional Size in inches of the image with the diffraction spots marked. Default is (15, 15) colormap: str, optional Colormap of the image. Default is inferno """ self.gaussval = gaussval if gaussval > 0: self.gblur = scnd.gaussian_filter(self.image, gaussval) self.imcleaned = st.util.image_normalizer(self.image - self.gblur) self.gauss_clean = gaussval plt.figure(figsize=imsize) plt.imshow(self.imcleaned, cmap=colormap) scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off")
def plot_image_data(data, min_val, max_val, filename, title): sb = scalebar.ScaleBar(1e-6) sb.location = 'lower left' pyplot.imshow(data, extent=k[ecs].extent('xz'), vmin=min_val, vmax=max_val, interpolation='nearest', origin='lower') pyplot.colorbar() sb = scalebar.ScaleBar(1e-6) sb.location = 'lower left' ax = pyplot.gca() ax.xaxis.set_visible(False) ax.yaxis.set_visible(False) ax.add_artist(sb) pyplot.title(title) pyplot.xlim(k[ecs].extent('x')) pyplot.ylim(k[ecs].extent('z')) pyplot.savefig(os.path.join(outdir, filename)) pyplot.close()
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 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 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 get_cbed(self, imsize=(15, 15)): self.cbed = np.median(self.data_4D, axis=(0, 1)) self.beam_x, self.beam_y, self.beam_r = st.util.sobel_circle(self.cbed) self.inverse = self.aperture / (self.beam_r * self.wavelength) plt.figure(figsize=imsize) plt.imshow(self.cbed) scalebar = mpss.ScaleBar(self.inverse, "1/pm", mpss.SI_LENGTH_RECIPROCAL) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off")
def show_image(self, imsize=(15, 15), colormap="inferno"): """ Parameters ---------- imsize: tuple, optional Size in inches of the image with the diffraction spots marked. Default is (15, 15) colormap: str, optional Colormap of the image. Default is inferno """ plt.figure(figsize=imsize) plt.imshow(self.image, cmap=colormap) scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off")
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 plot_gpa_strain(self, mval=0, imsize=(20, 20)): """ Use the calculated strain matrices to plot the strain maps Parameters ---------- mval: float, optional The maximum strain value that will be plotted. Default is 0, upon which the maximum strain percentage will be calculated, which will be used for plotting. imsize: tuple, optional Size in inches of the image with the diffraction spots marked. Default is (20, 20) Notes ----- Uses `matplotlib.gridspec` to plot the strain maps of the four types of strain calculated through geometric phase analysis. """ fontsize = int(np.mean(np.asarray(imsize))) if mval == 0: vm = 100 * np.amax( np.abs( np.concatenate( (self.e_yy, self.e_xx, self.e_dg, self.e_th), axis=1))) else: vm = mval sc_font = {"weight": "bold", "size": fontsize} mpl.rc("font", **sc_font) fig = plt.figure(figsize=imsize) gs = mpgs.GridSpec(2, 2) ax1 = plt.subplot(gs[0, 0]) ax2 = plt.subplot(gs[0, 1]) ax3 = plt.subplot(gs[1, 0]) ax4 = plt.subplot(gs[1, 1]) ax1.imshow(-100 * self.e_xx, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax1.add_artist(scalebar) at = mploff.AnchoredText( r"$\mathrm{\epsilon_{xx}}$", 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") ax2.imshow(-100 * self.e_dg, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax2.add_artist(scalebar) at = mploff.AnchoredText( r"$\mathrm{\epsilon_{xy}}$", 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") ax3.imshow(-100 * self.e_th, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax3.add_artist(scalebar) at = mploff.AnchoredText( r"$\mathrm{\epsilon_{\theta}}$", prop=dict(size=fontsize), frameon=True, loc="upper left", ) at.patch.set_boxstyle("round, pad= 0., rounding_size= 0.2") ax3.add_artist(at) ax3.axis("off") im = ax4.imshow(-100 * self.e_yy, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax4.add_artist(scalebar) at = mploff.AnchoredText( r"$\mathrm{\epsilon_{yy}}$", prop=dict(size=fontsize), frameon=True, loc="upper left", ) at.patch.set_boxstyle("round, pad= 0., rounding_size= 0.2") ax4.add_artist(at) ax4.axis("off") p1 = ax1.get_position().get_points().flatten() p4 = ax4.get_position().get_points().flatten() ax_cbar = fig.add_axes([p1[0] - 0.075, -0.01, p4[2] + 0.05, 0.02]) cbar = plt.colorbar(im, cax=ax_cbar, orientation="horizontal") cbar.set_label("Strain (%)", **sc_font) plt.autoscale()
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 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()
def add_scalebar(ax, scale=1e-6): sb = scalebar.ScaleBar(scale) sb.location = 'lower left' ax.xaxis.set_visible(False) ax.yaxis.set_visible(False) ax.add_artist(sb)
def show_peaks(self, imsize=(15, 15), style="together"): if not self.refining_check: raise RuntimeError( "Please refine the atom peaks first as refine_peaks()") togsize = tuple(np.asarray((2, 1)) * np.asarray(imsize)) spot_size = int(np.amin(np.asarray(imsize))) big_size = int(3 * spot_size) if style == "together": plt.figure(figsize=imsize) plt.imshow(self.imcleaned, cmap="magma") plt.scatter( self.peaks[:, 1], self.peaks[:, 0], c="c", s=big_size, label="Original Peaks", ) plt.scatter( self.refined_peaks[:, 1], self.refined_peaks[:, 0], c="r", s=spot_size, label="Fitted Peaks", ) plt.gca().legend(loc="upper left", markerscale=3, framealpha=1) scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off") else: plt.figure(figsize=togsize) plt.subplot(1, 2, 1) plt.imshow(self.imcleaned, cmap="magma") plt.scatter( self.peaks[:, 1], self.peaks[:, 0], c="b", s=spot_size, label="Original Peaks", ) plt.gca().legend(loc="upper left", markerscale=3, framealpha=1) scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off") plt.subplot(1, 2, 2) plt.imshow(self.imcleaned, cmap="magma") plt.scatter( self.refined_peaks[:, 1], self.refined_peaks[:, 0], c="k", s=spot_size, label="Fitted Peaks", ) plt.gca().legend(loc="upper left", markerscale=3, framealpha=1) scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" plt.gca().add_artist(scalebar) plt.axis("off")
def correct_dpc(self, imsize=(30, 17)): """ This corrects for the rotation angle of the pixellated detector with respect to the optic axis. Some pixellated detectors flip the image, and if there is an image flip, it corrects it too. The mechanism of this, we compare the gradient of both the flipped and the unflipped DPC data at multiple rotation angles, and the value that has the highest relative contrast with the ADF-STEM image is taken as 90 degrees from the correct angle. """ 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)))) / (10**9) fontsize = int(0.9 * np.max(imsize)) sc_font = {"weight": "bold", "size": fontsize} plt.figure(figsize=imsize) gs = mpgs.GridSpec(imsize[1], imsize[0]) ax1 = plt.subplot(gs[0:15, 0:15]) ax2 = plt.subplot(gs[0:15, 15:30]) ax3 = plt.subplot(gs[15:17, :]) ax1.imshow(self.XComC / (10**9), 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") ax2.imshow(self.YComC / (10**9), 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") sb = np.zeros((10, 1000), dtype=np.float) for ii in range(10): sb[ii, :] = np.linspace(-vm, vm, 1000) ax3.imshow(sb, cmap="RdBu_r") ax3.yaxis.set_visible(False) x1 = np.linspace(0, 1000, 8) ax3.set_xticks(x1) ax3.set_xticklabels(np.round(np.linspace(-vm, vm, 8), 2)) for axis in ["top", "bottom", "left", "right"]: ax3.spines[axis].set_linewidth(2) ax3.spines[axis].set_color("black") ax3.xaxis.set_tick_params(width=2, length=6, direction="out", pad=10) ax3.set_title(r"$\mathrm{Beam\: Shift\: \left(nm^{-1}\right)}$", **sc_font) plt.tight_layout() self.MomentumX = self.planck * self.XComC self.MomentumY = self.planck * self.YComC # assuming infinitely thin sample self.e_fieldX = self.MomentumX / self.e_charge self.e_fieldY = self.MomentumY / self.e_charge
x1, x2, y1, y2 = origin[0], origin[0] + width, origin[1], origin[1] + width axin.set_xlim(x1, x2) axin.set_ylim(y1, y2) axin.set_xticks([]) axin.set_yticks([]) plot.indicate_inset_zoom(axin, edgecolor='0.5') plot.set_title(title) plot.set_xticks([]) plot.set_yticks([]) if idx == 0: scale = scalebar.ScaleBar(0.635, 'um', location=2, box_color='k', color='w', box_alpha=0) plot.add_artist(scale) plt.subplots_adjust(wspace=0.0, hspace=0.16, left=0, right=1, top=0.945, bottom=0) plt.savefig(os.path.join(gpath, 'images_noise.pdf'))
def initial_dpc(self, imsize=(30, 17), normalize=True): """ This calculates the initial DPC center of mass shifts by measuring the center of mass of each image in the 4D-STEM dataset, and then comparing that center of mass with the average disk center of the entire dataset. """ 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) if normalize: self.YCom = self.YCom - np.mean(self.YCom) self.XCom = self.XCom - np.mean(self.XCom) vm = (np.amax(np.abs(np.concatenate( (self.XCom, self.YCom), axis=1)))) / (10**9) fontsize = int(0.9 * np.amax(np.asarray(imsize))) sc_font = {"weight": "bold", "size": fontsize} plt.figure(figsize=imsize) gs = mpgs.GridSpec(imsize[1], imsize[0]) ax1 = plt.subplot(gs[0:15, 0:15]) ax2 = plt.subplot(gs[0:15, 15:30]) ax3 = plt.subplot(gs[15:17, :]) ax1.imshow(self.XCom / (10**9), 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") ax2.imshow(self.YCom / (10**9), 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") sb = np.zeros((10, 1000), dtype=np.float) for ii in range(10): sb[ii, :] = np.linspace(-vm, vm, 1000) ax3.imshow(sb, cmap="RdBu_r") ax3.yaxis.set_visible(False) x1 = np.linspace(0, 1000, 8) ax3.set_xticks(x1) ax3.set_xticklabels(np.round(np.linspace(-vm, vm, 8), 2)) for axis in ["top", "bottom", "left", "right"]: ax3.spines[axis].set_linewidth(2) ax3.spines[axis].set_color("black") ax3.xaxis.set_tick_params(width=2, length=6, direction="out", pad=10) ax3.set_title(r"$\mathrm{Beam\: Shift\: \left(nm^{-1}\right)}$", **sc_font) plt.tight_layout()
min_max[:, :, 0] = max_outline min_max[:, :, 1] = min_outline s = min_max.sum(axis=2) print("S shape: " + str(s.shape)) min_max[s == 0] = 1 print(max_outline.shape) print(min_max.max()) plt.cla() plt.imshow(min_max) plt.xlim(950, 2100) plt.ylim(1750, 500) plt.tight_layout() scaleBar = scalebar.ScaleBar((1 / pix_per_mm), 'mm') # 1 pixel = 1/2 mm plt.gca().add_artist(scaleBar) plt.axis('off') plt.title(center[0], fontsize=title_size) plt.savefig('min_max_test_' + center[0] + '.png', dpi=600) #plt.show() plt.cla() print("contour") if ('15mm Parallel' in center[0] or "15 to 10" in center[0]): exp_Tmap15.append(mfill) print("append 15") if ('20mm Parallel' in center[0] or "20 to 15" in center[0]): exp_Tmap20.append(mfill)
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 plot_gpa_strain(self, mval=0, imwidth=15): """ Use the calculated strain matrices to plot the strain maps Parameters ---------- mval: float, optional The maximum strain value that will be plotted. Default is 0, upon which the maximum strain percentage will be calculated, which will be used for plotting. imwidth: int, optional Size in inches of the image with the diffraction spots marked. Default is 15 Notes ----- Uses `matplotlib.gridspec` to plot the strain maps of the four types of strain calculated through geometric phase analysis. """ fontsize = int(imwidth) if mval == 0: vm = 100 * np.amax( np.abs( np.concatenate( (self.e_yy, self.e_xx, self.e_dg, self.e_th), axis=1))) else: vm = mval sc_font = {"weight": "bold", "size": fontsize} mpl.rc("font", **sc_font) imsize = (int(imwidth), int(imwidth * 1.1)) plt.figure(figsize=imsize) gs = mpgs.GridSpec(11, 10) ax1 = plt.subplot(gs[0:5, 0:5]) ax2 = plt.subplot(gs[0:5, 5:10]) ax3 = plt.subplot(gs[5:10, 0:5]) ax4 = plt.subplot(gs[5:10, 5:10]) ax5 = plt.subplot(gs[10:11, :]) ax1.imshow(-100 * self.e_xx, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax1.add_artist(scalebar) at = mploff.AnchoredText( r"$\mathrm{\epsilon_{xx}}$", 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") ax2.imshow(-100 * self.e_dg, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax2.add_artist(scalebar) at = mploff.AnchoredText( r"$\mathrm{\epsilon_{xy}}$", 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") ax3.imshow(-100 * self.e_th, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax3.add_artist(scalebar) at = mploff.AnchoredText( r"$\mathrm{\epsilon_{\theta}}$", prop=dict(size=fontsize), frameon=True, loc="upper left", ) at.patch.set_boxstyle("round, pad= 0., rounding_size= 0.2") ax3.add_artist(at) ax3.axis("off") ax4.imshow(-100 * self.e_yy, vmin=-vm, vmax=vm, cmap="RdBu_r") scalebar = mpss.ScaleBar(self.calib, self.calib_units) scalebar.location = "lower right" scalebar.box_alpha = 1 scalebar.color = "k" ax4.add_artist(scalebar) at = mploff.AnchoredText( r"$\mathrm{\epsilon_{yy}}$", prop=dict(size=fontsize), frameon=True, loc="upper left", ) at.patch.set_boxstyle("round, pad= 0., rounding_size= 0.2") ax4.add_artist(at) ax4.axis("off") sb = np.zeros((10, 1000), dtype=np.float) for ii in range(10): sb[ii, :] = np.linspace(-vm, vm, 1000) ax5.imshow(sb, cmap="RdBu_r") ax5.yaxis.set_visible(False) no_labels = 9 x1 = np.linspace(0, 1000, no_labels) ax5.set_xticks(x1) ax5.set_xticklabels(np.round(np.linspace(-vm, vm, no_labels), 4)) for axis in ["top", "bottom", "left", "right"]: ax5.spines[axis].set_linewidth(2) ax5.spines[axis].set_color("black") ax5.xaxis.set_tick_params(width=2, length=6, direction="out", pad=10) ax5.set_title("Strain (%)", **sc_font) plt.autoscale()