def plotFFT(self, output): # Calculate the FFT magnitude. f, fft = util.fft(self.frTime, self.frSignal) mag = np.abs(fft) # Plot the FFT magnitude. plt.plot(f, mag) # Axis limits. plt.xlim(0, 8000) plt.ylim(0, np.max(mag[(f > 1000)]) * 1.05) style.xlabel("Frequency (kHz)") style.ylabel("Arbitrary Units") plt.savefig(f"{output}/fft.pdf") # Save with a log scale. plt.yscale("log") plt.ylim(np.min(mag[(f < 8000)]), None) plt.savefig(f"{output}/fft_log.pdf") # Clear the figure. plt.clf()
def plot(self, output, axis="f"): # Plot the specified distribution. plt.plot(self.axes[axis][self.physical], self.signal[self.physical], 'o-') # Plot the magic quantity as a vertical line. plt.axvline(util.magic[axis], ls=":", c="k", label="Magic") # Axis labels. label, units = util.labels[axis]['plot'], util.labels[axis]['units'] style.xlabel(f"{label}" + (f" ({units})" if units != "" else "")) style.ylabel("Arbitrary Units") # Infobox containing mean and standard deviation. style.databox( (fr"\langle {util.labels[axis]['math']} \rangle", self.getMean(axis), self.getMeanError(axis), util.labels[axis]["units"]), (fr"\sigma_{{{util.labels[axis]['math']}}}", self.getWidth(axis), self.getWidthError(axis), util.labels[axis]["units"]), left=False if axis == "c_e" else True) # Add the legend. plt.legend(loc="upper right" if axis != "c_e" else "center right") # Save to disk. plt.savefig(output) # Clear the figure. plt.clf()
def plotMagnitude(self, output): # Calculate the cosine, sine, and Fourier (magnitude) transforms. real = self.transform(self.t0) imag = self.transform(self.t0, sine=True) mag = np.sqrt(real**2 + imag**2) # Plot the magnitude, real, and imaginary parts. plt.plot(self.frequency, mag, 'o-', label="Fourier Magnitude") plt.plot(self.frequency, real, 'o-', label="Real Part (Cosine)") plt.plot(self.frequency, imag, 'o-', label="Imag. Part (Sine)") plt.axhline(0, ls=':', c="k") plt.legend() # Axis labels. style.xlabel("Frequency (kHz)") style.ylabel("Arbitrary Units") plt.savefig(f"{output}/magnitude.pdf") plt.clf() # Plot the phase. plt.plot(self.frequency, np.arctan2(imag, real), 'o-') style.xlabel("Frequency (kHz)") style.ylabel("Phase (rad)") plt.savefig(f"{output}/phase.pdf") plt.clf()
def plot(self, output, endTimes): if output is not None: # Plot the signal. plt.plot(self.time, self.signal) # Label the axes. style.xlabel(r"Time ($\mu$s)") style.ylabel("Intensity") # Save the figure over a range of time axis limits (in us). for end in endTimes: # Set the time limits. plt.xlim(4, end) # Update the intensity limits. view = self.signal[(self.time >= 4) & (self.time <= end)] plt.ylim(np.min(view), np.max(view)) # Save the figure. plt.savefig(f"{output}/signal/FastRotation_{end}us.pdf") # Clear the figure. plt.clf()
def plotCorrelation(self, output): style.imshow(self.corr, label="Correlation", vmin=-1, vmax=1) style.xlabel(f"Frequency Bin ($\Delta f = {self.transform.df}$ kHz)") style.ylabel(f"Frequency Bin ($\Delta f = {self.transform.df}$ kHz)") plt.savefig(output) plt.clf()
def plot( self, # Path to desired output file. output=None, # Assume plot objects exist already in plt.gca(), and update them for speed. update=False): # Make a text label for t0. label = f"$t_0 = {self.t0*1000:.4f}$ ns" # Make a plot from scratch. if not update: # Plot the transform, background points, and background fit. plt.plot(self.frequency, self.signal, 'o-', label="Cosine Transform") plt.plot(self.x, self.y, 'ko', label="Background") plt.plot(self.frequency, self.result, 'g', label="Background Fit") # Display the t0 label. plt.text(0.04, 0.95, label, ha="left", va="top", transform=plt.gca().transAxes) # Make the axis labels and legend. style.xlabel("Frequency (kHz)") style.ylabel("Arbitrary Units") plt.legend() # Save to disk and clear the figure, if specified. if output is not None: plt.savefig(output) plt.clf() # Update the existing plot objects for speed, assuming the above order. else: # Update the transform, background points, and background fit. plt.gca().lines[0].set_ydata(self.signal) plt.gca().lines[1].set_ydata(self.y) plt.gca().lines[2].set_ydata(self.result) # Update the t0 label. plt.gca().findobj(matplotlib.text.Text)[0].set_text(label) # Rescale the y-axis. plt.gca().relim() plt.gca().autoscale()
def plot(self, times=[]): style.setStyle() self.frequencies.plot() style.xlabel("Cyclotron Frequency (kHz)") style.ylabel("Entries / 1 kHz") plt.savefig(f"{self.directory}/frequencies.pdf") plt.close() self.profile.plot() style.xlabel("Injection Time (ns)") style.ylabel("Entries / 1 ns") plt.savefig(f"{self.directory}/profile.pdf") plt.close() self.joint.plot() style.xlabel("Injection Time (ns)") style.ylabel("Cyclotron Frequency (kHz)") plt.savefig(f"{self.directory}/joint.pdf") plt.close() self.signal.plot() style.xlabel(r"Time (ns)") style.ylabel("Intensity / 1 ns") plt.savefig(f"{self.directory}/signal.pdf") for i in range(len(times)): if self.backward: plt.xlim(-times[i], times[i]) else: plt.xlim(0, times[i]) plt.savefig(f"{self.directory}/signal_{i}.pdf") plt.close()
def plotOptimization(self, outDir, mode="coarse", all=False): if mode == "coarse": scanResults = self.coarseScan elif mode == "fine": scanResults = self.fineScan else: raise ValueError(f"Optimization mode '{mode}' not recognized.") scanMetric = np.array([result.chi2ndf for result in scanResults]) label = r"$\chi^2$/ndf" # Extract the t0 times. times = np.array([result.t0 for result in scanResults]) # Plot the SSE or chi2/ndf. plt.plot(times * 1000, scanMetric, 'o-') # For a chi2/ndf plot... if mode == "fine": # Show the one-sigma t0 bounds as a shaded rectangle. plt.axvspan((self.t0 - self.err_t0) * 1000, (self.t0 + self.err_t0) * 1000, alpha=0.2, fc="k", ec=None) # Plot the optimized t0 as a vertical line. plt.axvline(self.t0 * 1000, c="k", ls="--") # Show the horizontal reference line where chi2/ndf = 1. plt.axhline(1, c="k", ls=":") # Axis labels. style.xlabel("$t_0$ (ns)") style.ylabel(label) plt.ylim(0, None) # Save the result to disk, and clear the figure. plt.savefig(f"{outDir}/{mode}_scan.pdf") plt.clf() # Plot every background fit from the scan, in a multi-page PDF. if all: # Temporarily turn off LaTeX rendering for faster plots. latex = plt.rcParams["text.usetex"] plt.rcParams["text.usetex"] = False # Initialize the multi-page PDF file for scan plots. pdf = PdfPages(f"{outDir}/AllFits_{mode}.pdf") # Initialize a plot of the background fit. scanResults[0].plot() # Plot each background fit, updating the initialized plot each time. for i in range(len(times)): scanResults[i].plot(update=True) pdf.savefig() # Close the multi-page PDF, and clear the current figure. pdf.close() plt.clf() # Resume LaTeX rendering, if it was enabled before. if latex: plt.rcParams["text.usetex"] = True