files.sort() print(files) import matplotlib as mpl from mpl_toolkits.mplot3d import Axes3D import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm index = 0 colors = cm.rainbow(np.linspace(0, 1, len(files))) fig, ax = plt.subplots() ax2 = plt.axes([0, 0, 1, 1]) ip = InsetPosition(ax, [0.05, 0.4, 0.5, 0.5]) ax2.set_axes_locator(ip) mark_inset(ax, ax2, loc1=2, loc2=4, fc="none", ec='0.5') offset = 0.0 for x in files: x, y = np.loadtxt(directory + str(x), unpack=True) print(x) index += 1 ax.plot(1239.8 / x, y + offset, label=str(float(files[index - 1])), c=colors[index - 1]) ax2.plot(1239.8 / x,
pl.grid() # inset plot # akuederle.com/matplotlib-zoomed-up-inset # 'upper right' : 1, # 'upper left' : 2, # 'lower left' : 3, # 'lower right' : 4 fig, ax = plt.subplots() # create a new figure with a default 111 subplot ax.plot(overview_data_x, overview_data_y) # zoom-factor: 2.5, location: upper-left axins = zoomed_inset_axes(ax, 2.5, loc=2) locate the position of inset # left down width hight fraction of main axix ip = InsetPosition(ax, [0.1, 0.05, 0.4, 0.3]) axins.set_axes_locator(ip) axins.plot(overview_data_x, overview_data_y) x1, x2, y1, y2 = 47, 60, 3.7, 4.6 # specify the limits axins.set_xlim(x1, x2) # apply the x-limits axins.set_ylim(y1, y2) # apply the y-limits plt.yticks(visible=False) plt.xticks(visible=False) mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") # Error bar: # example data x = np.arange(0.1, 4, 0.5)
def run(_cfg, fout=None, source_data=None): cfg = ConfigParser(interpolation=ExtendedInterpolation()) cfg.read(_cfg) left = aux.read.into_list(cfg['mat']['left_nodes']) right = aux.read.into_list(cfg['mat']['right_nodes']) cclass = aux.read.into_dict(cfg['mat']['class']) N = from_db('N2U', adjacency=True, dataType='networkx', remove=REMOVE) J = from_db('JSH', adjacency=True, dataType='networkx', remove=REMOVE) SD = [['cell_class', 'adult_left', 'adult_right', 'l4_left', 'l4_right']] adult_left, adult_right, l4_left, l4_right = [], [], [], [] delta_l4, delta_adult = [], [] for (l, r) in zip(left, right): if l in BAD: continue if not N.A.has_node(l): continue if not N.A.has_node(r): continue if not J.A.has_node(l): continue if not J.A.has_node(r): continue adult_left.append(N.A.degree(l)) adult_right.append(N.A.degree(r)) l4_left.append(J.A.degree(l)) l4_right.append(J.A.degree(r)) delta_l4.append(abs(J.A.degree(l) - J.A.degree(r))) delta_adult.append(abs(N.A.degree(l) - N.A.degree(r))) tmp = [ cclass[l], N.A.degree(l), N.A.degree(r), J.A.degree(l), J.A.degree(r) ] SD.append(tmp) i = np.argsort(adult_left) delta_l4 = np.array(delta_l4)[i] delta_adult = np.array(delta_adult)[i] adult_left = np.array(adult_left) #Plot data fig, ax = plt.subplots(1, 1, figsize=(3, 3)) s = 4 print(len(adult_left)) ax.scatter(adult_left, adult_left, color='k', marker='s', s=s, label="Adult left") ax.scatter(adult_left, adult_right, color='b', marker='o', s=s, label="Adult right") ax.scatter(adult_left, l4_left, color='g', marker='^', s=s, label="L4 left") ax.scatter(adult_left, l4_right, color='r', marker="v", s=s, label="L4 right") ax.set_xlabel('Adult left neighborhood size', fontsize=7) ax.set_ylabel('Neighborhood size', fontsize=7) ax.legend(fontsize=5) ax2 = plt.axes([0, 0, 1, 1]) ip = InsetPosition(ax, [0.67, 0.13, 0.3, 0.3]) ax2.set_axes_locator(ip) ax2.bar(adult_left[i], delta_l4, color='r', linewidth=3, label='L4') ax2.bar(adult_left[i], delta_adult, color='b', linewidth=3, label='Adult') ax2.set_xlabel('Size', fontsize=6) ax2.set_ylabel('Spread', fontsize=6) ax2.legend(fontsize=5) ax2.set_ylim([0, 30]) for tick in ax2.xaxis.get_major_ticks(): tick.label.set_fontsize(5) for tick in ax2.yaxis.get_major_ticks(): tick.label.set_fontsize(5) plt.tight_layout() if fout: plt.savefig(fout) plt.show() if source_data: aux.write.from_list(source_data, SD)
def plot_force_position_vs_time(time_data, FDC_data, y_data, p): '''Make Fig. 2 panel (a) is driving force vs. time panel (b) is y/period vs. time ''' #for plot #calculate the driving force from F_DC and time F_AC = p['F_AC'] freq = p['freq'] period = p['period'] fig = plt.figure(figsize=(8, 8)) #.25)) gs = gridspec.GridSpec(2, 1) ax1 = fig.add_subplot(gs[0, 0]) #scatter plot of particles ax2 = fig.add_subplot(gs[1, 0]) #,sharex=ax1) #scatter plot of particles # Create a set of inset Axes: #these should fill the bounding box allocated to # them. ax3 = plt.axes([0, 0, 1, 1]) # Manually set the position and relative size of the inset axes within ax1 ip = InsetPosition(ax2, [0.62, 0.18, 0.33, 0.42]) ax3.set_axes_locator(ip) L = [1.4, 2.75] N = 1 add_contour(ax3, L, N) #calculate from np.array rather than incrementally from subroutines F_drive = FDC_data + F_AC * np.sin(2 * np.pi * freq * time_data) #max occurs at # 2*np.pi*freq*time_data = m*pi/2, where m = 1, 5, 9, 13, ... # time = m/(4*freq) #plot the force vs. time data #ax1.plot(time_data,FDC_data,label="F$^{\mathrm{dc}}$") ax1.plot(time_data, F_drive, label="F$_d$(t)", lw=5) #plot normalized position by period vs. time ax2.plot(time_data, y_data / period, lw=5) #,'o--') #,markevery=100) ax3.plot(time_data, y_data / period, lw=5) #,'o--') #,markevery=100) #set all the labels, ax1 and ax2 have the same time axes ax1.set_ylabel(r"$F_d(t)$") ax2.set_xlabel(r"time ($\tau$)") ax2.set_ylabel(r"y/$\lambda$") ax3.set_xlabel(r"time", backgroundcolor="white") #,y=10) ax3.set_ylabel(r"y/$\lambda$") ax3.xaxis.set_label_coords(0.5, -0.05) plt.setp(ax1.get_xticklabels(), visible=False) ax1.set_xlim(0, time_data[-1] + 1) ax2.set_xlim(0, time_data[-1] + 1) ax3.set_xlim(100, 200) ax3.set_ylim(*L) #1.5,2.9) ax1.text(-0.19, 0.86, "(a)", transform=ax1.transAxes, backgroundcolor="white") ax2.text(-0.19, 0.86, "(b)", transform=ax2.transAxes) ax2.grid(axis='both', which='both') ax1.grid(axis='both', which='both') plt.tight_layout(pad=0.1) #,h_pad=-0.3) plt.savefig(parameters['filename']) return
plt.xlim([0, x_max]) plt.ylim([-2.5, 3.8]) ax1 = plt.gca() x_min = 1200 print(step_4) step_4_mask = numpy.logical_and(step_4 >= x_min, step_4 <= x_max) step_6_mask = numpy.logical_and(step_6 >= x_min, step_6 <= x_max) # bottom, left, width, height ax2 = plt.axes([-2, 1800., 200, 1.0]) # Manually set the position and relative size of the inset axes within ax1 ip = InsetPosition(ax1, [0.6, 0.25, 0.3, 0.4]) ax2.set_axes_locator(ip) # Mark the region corresponding to the inset axes on ax1 and draw lines # in grey linking the two axes. mark_inset(ax1, ax2, loc1=3, loc2=1, fc="black", alpha=0.5, ec='black') step_4 = step_4[step_4_mask] energy_4 = energy_4[step_4_mask] err_4 = err_4[step_4_mask] step_6 = step_6[step_6_mask] energy_6 = energy_6[step_6_mask] err_6 = err_6[step_6_mask] plt.plot(step_4, energy_4, label=r"$\Lambda = 4~$fm${}^{-1}$") plt.fill_between(step_4, energy_4 - err_4, energy_4 + err_4, alpha=0.5)
line_target, = ax.plot([], [], [], 'ro-', ms=5, lw=2) line_ghost, = ax.plot([], [], [], 'co-', ms=10, lw=2) time_template = 'Time = %.1f/%.0fs' time_text = ax.text2D(0.05, 0.95, '', transform=ax.transAxes) time_text2 = ax.text2D(0.65, 0.95, 'Q-Learning Control', transform=ax.transAxes) time_text3 = ax.text2D(0.65, 0.90, 'Controller: PD', transform=ax.transAxes) if inset == 1: ax4 = plt.axes([0, 0, 1, 1]) # set position manually (x pos, y pos, x len, y len) ip = InsetPosition(ax, [0, 0.7, 0.2, 0.2]) ax4.set_axes_locator(ip) # cool, make lines to point (save this for later) #mark_inset(ax2, ax3, loc1=2, loc2=4, fc="none", ec='0.5') # data line2, = ax4.plot([], [], '--', c='b', mew=2, alpha=0.8, label='Cost') ax5 = ax4.twinx() ax5.set_axes_locator(ip) # data line3, = ax4.plot([], [], '-', c='g', mew=2, alpha=0.8, label='Explore') ax4.set_ylabel('Cost') ax4.set_xlim(0, max(t_all)) ax4.set_ylim(0, 1) ax4.tick_params(axis='y', labelcolor='b')
def check3(t=200, rho=4.66): import numpy as np np.set_printoptions(linewidth=10000) qmax = 0.1 t, qmax = 2000, 0.05 #t, qmax = 20, 0.4 q = np.linspace(0.0, qmax, 6000)[1:] layers = [ # depth rho irho sigma [0, 0.0, 0.0, 0.0], #[200, 2.0, 0.0, 0.0], [t, rho, 0.0, 0.0], [0, 0, 0.0, 0.0], #[ 0, 2.07, 0.0, 0.0], ] # add absorption # layers[1][2] = 1.0 vdepth, vrho, virho, vsigma = [np.asarray(v) for v in zip(*layers)] if 1: steps = 2001 #portion = 0.9 portion = 0.0 thickness = t flat = thickness * portion ends = thickness * (1 - portion) z = np.linspace(-3, 3, steps) vrho = np.exp(-0.5 * z**2) * rho virho = 0 * rho vdepth = np.ones_like(z) * ends / steps vdepth[int((steps - 1) / 2)] = flat vsigma = 0 * rho if 0: steps = 2001 thickness, portion = t, 0.0 flat = thickness * portion ends = thickness * (1 - portion) z = np.linspace(-3, 3, steps) vrho = np.exp(-0.5 * z**2) * rho vrho += -np.exp(-0.5 * (z - 1)**2 * 4) * rho virho = 0 * rho vdepth = np.ones_like(z) * ends / steps vdepth[int((steps - 1) / 2)] = flat vsigma = 0 * rho ## normalize to same amount of scattering density #total = rho*t #vrho *= total/np.sum(vrho*vdepth) wave = refl_tr(q / 2, vdepth, vrho, irho=virho, sigma=vsigma) #print("shape", layers.shape) r = wave[0, 1] import matplotlib.pyplot as plt from mpl_toolkits.axes_grid.inset_locator import InsetPosition scale = q * 0 + 1 #scale = q**4 plt.plot(q, scale * r.real, '-b', label='real', zorder=2) plt.plot(q, scale * r.imag, '-r', label='imag') plt.plot(q, scale * abs(r**2), '-g', label='magnitude') #plt.yscale('symlog', linthreshy=1e-6) #plt.legend() plt.grid(True) ax = plt.gca() inset = plt.axes([0, 0, 1, 1]) inset.step(np.cumsum(vdepth), vrho, '-g', label='rho') #inset.step(np.cumsum(vdepth), virho, '-m', label='irho') inset.set_axes_locator(InsetPosition(ax, [0.6, 0.7, 0.4, 0.3])) inset.patch.set_alpha(0.5) inset.patch.set_color([0.9, 0.9, 0.8])
def attributes_diagram(rel_objs, obj_labels, colors, markers, filename, figsize=(8, 8), xlabel="Forecast Probability", ylabel="Observed Relative Frequency", ticks=np.arange(0, 1.05, 0.05), dpi=300, title="Attributes Diagram", legend_params=None, inset_params=None, inset_position=(0.12, 0.72, 0.25, 0.25), bootstrap_sets=None, ci=(2.5, 97.5)): """ Plot reliability curves against a 1:1 diagonal to determine if probability forecasts are consistent with their observed relative frequency. Also adds gray areas to show where the climatological probabilities lie and what areas result in a positive Brier Skill Score. Args: rel_objs (list): List of DistributedReliability objects. obj_labels (list): List of labels describing the forecast model associated with each curve. colors (list): List of colors for each line markers (list): List of line markers filename (str): Where to save the figure. figsize (tuple): (Width, height) of the figure in inches. xlabel (str): X-axis label ylabel (str): Y-axis label ticks (array): Tick value labels for the x and y axes. dpi (int): resolution of the saved figure in dots per inch. title (str): Title of figure legend_params (dict): Keyword arguments for the plot legend. inset_params (dict): Keyword arguments for the inset axis. inset_position (tuple): Position of the inset axis in normalized axes coordinates (left, bottom, width, height) bootstrap_sets (list): A list of arrays of bootstrapped DistributedROC objects. If not None, confidence regions will be plotted. ci (tuple): tuple of bootstrap confidence interval percentiles """ if legend_params is None: legend_params = dict(loc=4, fontsize=10, framealpha=1, frameon=True) if inset_params is None: inset_params = dict(width="25%", height="25%", loc=2, axes_kwargs=dict(axisbg='white')) fig, ax = plt.subplots(figsize=figsize) plt.plot(ticks, ticks, "k--") inset_hist = inset_axes(ax, **inset_params) ip = InsetPosition(ax, inset_position) inset_hist.set_axes_locator(ip) climo = rel_objs[0].climatology() no_skill = 0.5 * ticks + 0.5 * climo skill_x = [climo, climo, 1, 1, climo, climo, 0, 0, climo] skill_y = [climo, 1, 1, no_skill[-1], climo, 0, 0, no_skill[0], climo] f = ax.fill(skill_x, skill_y, "0.8") f[0].set_zorder(1) ax.plot(ticks, np.ones(ticks.shape) * climo, "k--") if bootstrap_sets is not None: for b, b_set in enumerate(bootstrap_sets): brel_curves = np.vstack([ b_rel.reliability_curve()["Positive_Relative_Freq"].values for b_rel in b_set ]) rel_range = np.nanpercentile(brel_curves, ci, axis=0) fb = ax.fill_between(b_rel.thresholds[:-1], rel_range[1], rel_range[0], alpha=0.5, color=colors[b]) fb.set_zorder(2) for r, rel_obj in enumerate(rel_objs): rel_curve = rel_obj.reliability_curve() ax.plot(rel_curve["Bin_Start"], rel_curve["Positive_Relative_Freq"], color=colors[r], marker=markers[r], label=obj_labels[r]) inset_hist.semilogy(rel_curve["Bin_Start"] * 100, rel_obj.frequencies["Total_Freq"][:-1], color=colors[r], marker=markers[r]) inset_hist.set_xlabel("Forecast Probability") inset_hist.set_ylabel("Frequency") ax.annotate("No Skill", (0.6, no_skill[12]), rotation=22.5) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) ax.set_xticks(ticks) ax.set_xticklabels((ticks * 100).astype(int)) ax.set_yticks(ticks) ax.set_yticklabels((ticks * 100).astype(int)) ax.legend(**legend_params) ax.set_title(title) plt.savefig(filename, dpi=dpi, bbox_inches="tight") plt.close()
def make_rq(data_dir): # set plotting style mpl.rcParams['font.size']=10 mpl.rcParams['legend.fontsize']='small' mpl.rcParams['figure.autolayout']=True mpl.rcParams['figure.figsize']=[8.0,6.0] # ================================================================== # define DAQ and other parameters #wsize = 12500 # size of event window in samples. 1 sample = 2 ns. #read event window width from the folder name if data_dir.find("3us") != -1: event_window = 3 if data_dir.find("25us") != -1: event_window = 25 # in us. wsize = int(500 * event_window) # samples per waveform # 12500 for 25 us vscale = (2000.0/16384.0) # = 0.122 mV/ADCC, vertical scale tscale = (8.0/4096.0) # = 0.002 µs/sample, time scale save_avg_wfm = False # get the average waveform passing some cut and save to file post_trigger = 0.5 # Was 0.2 for data before 11/22/19 trigger_time_us = event_window*(1-post_trigger) trigger_time = int(trigger_time_us/tscale) n_sipms = 8 n_channels = n_sipms+1 # includes sum # define top, bottom channels n_top = int((n_channels-1)/2) top_channels=np.array(range(n_top),int) bottom_channels=np.array(range(n_top,2*n_top),int) # sphe sizes in mV*sample ns_to_sample = 1024./2000. #convert spe size unit from mV*ns to mV*sample spe = {} with open(data_dir+"spe.txt", 'r') as file: for line in file: (key, val) = line.split() spe[key] = float(val)*ns_to_sample chA_spe_size = spe["ch0"]#29.02 chB_spe_size = spe["ch1"]#30.61 chC_spe_size = spe["ch2"]#28.87 chD_spe_size = spe["ch3"]#28.86*1.25 # scale factor (0.7-1.4) empirical as of Dec 9, 2020 chE_spe_size = spe["ch4"]#30.4 chF_spe_size = spe["ch5"]#30.44 chG_spe_size = spe["ch6"]#30.84 chH_spe_size = spe["ch7"]#30.3*1.8 # scale factor (1.6-2.2) empirical as of Dec 9, 2020 spe_sizes = [chA_spe_size, chB_spe_size, chC_spe_size, chD_spe_size, chE_spe_size, chF_spe_size, chG_spe_size, chH_spe_size] # ================================================================== #load in raw data t_start = time.time() block_size = 3000 n_block = 500 max_evts = n_block*block_size#5000 # 25000 # -1 means read in all entries; 25000 is roughly the max allowed in memory on the DAQ computer max_pts = -1 # do not change if max_evts > 0: max_pts = wsize * max_evts load_dtype = "int16" # pulse RQs to save # RQs to add: # Pulse level: channel areas (fracs; max fracs), TBA, rise time? (just difference of AFTs...) # Event level: drift time; S1, S2 area # Pulse class (S1, S2, other) # max number of pulses per event max_pulses = 4 p_start = np.zeros(( max_evts, max_pulses), dtype=int) p_end = np.zeros(( max_evts, max_pulses), dtype=int) p_found = np.zeros(( max_evts, max_pulses), dtype=int) #center of mass center_top_x = np.zeros(( max_evts, max_pulses)) center_top_y = np.zeros(( max_evts, max_pulses)) center_bot_x = np.zeros(( max_evts, max_pulses)) center_bot_y = np.zeros(( max_evts, max_pulses)) p_area = np.zeros(( max_evts, max_pulses)) p_max_height = np.zeros(( max_evts, max_pulses)) p_min_height = np.zeros(( max_evts, max_pulses)) p_width = np.zeros(( max_evts, max_pulses)) p_afs_2l = np.zeros((max_evts, max_pulses) ) p_afs_2r = np.zeros((max_evts, max_pulses) ) p_afs_1 = np.zeros((max_evts, max_pulses) ) p_afs_25 = np.zeros((max_evts, max_pulses) ) p_afs_50 = np.zeros((max_evts, max_pulses) ) p_afs_75 = np.zeros((max_evts, max_pulses) ) p_afs_99 = np.zeros((max_evts, max_pulses) ) p_hfs_10l = np.zeros((max_evts, max_pulses) ) p_hfs_50l = np.zeros((max_evts, max_pulses) ) p_hfs_10r = np.zeros((max_evts, max_pulses) ) p_hfs_50r = np.zeros((max_evts, max_pulses) ) p_mean_time = np.zeros((max_evts, max_pulses) ) p_rms_time = np.zeros((max_evts, max_pulses) ) # Channel level (per event, per pulse, per channel) p_start_ch = np.zeros((max_evts, max_pulses, n_channels-1), dtype=int) p_end_ch = np.zeros((max_evts, max_pulses, n_channels-1), dtype=int ) p_area_ch = np.zeros((max_evts, max_pulses, n_channels-1) ) p_area_ch_frac = np.zeros((max_evts, max_pulses, n_channels-1) ) p_area_top = np.zeros((max_evts, max_pulses)) p_area_bottom = np.zeros((max_evts, max_pulses)) p_tba = np.zeros((max_evts, max_pulses)) p_class = np.zeros((max_evts, max_pulses), dtype=int) # Event-level variables n_pulses = np.zeros(max_evts, dtype=int) n_s1 = np.zeros(max_evts, dtype=int) n_s2 = np.zeros(max_evts, dtype=int) sum_s1_area = np.zeros(max_evts) sum_s2_area = np.zeros(max_evts) drift_Time = np.zeros(max_evts) drift_Time_AS = np.zeros(max_evts) # for multi-scatter drift time, defined by the first S2. s1_before_s2 = np.zeros(max_evts, dtype=bool) n_wfms_summed = 0 avg_wfm = np.zeros(wsize) # Temporary, for testing low area, multiple-S1 events dt = np.zeros(max_evts) small_weird_areas = np.zeros(max_evts) big_weird_areas = np.zeros(max_evts) n_golden = 0 inn="" inn="" # used to control hand scan empty_evt_ind = np.zeros(max_evts) for j in range(n_block): ch_data = [] for ch_ind in range(n_sipms): ch_data.append(np.fromfile(data_dir + "wave"+str(ch_ind)+".dat", dtype=load_dtype, offset = block_size*wsize*j, count=wsize*block_size)) #t_end_load = time.time() #print("Time to load files: ", t_end_load-t_start) # scale waveforms to get units of mV/sample # then for each channel ensure we # have an integer number of events array_dtype = "float32" # using float32 reduces memory for big files, otherwise implicitly converts to float64 # matrix of all channels including the sum waveform v_matrix_all_ch = [] for ch_ind in range(n_sipms): V = vscale * ch_data[ch_ind].astype(array_dtype) / spe_sizes[ch_ind] V = V[:int(len(V) / wsize) * wsize] V = V.reshape(int(V.size / wsize), wsize) # reshape to make each channel's matrix of events v_matrix_all_ch.append(V) if ch_ind==0: v_sum = np.copy(V) else: v_sum += V v_matrix_all_ch.append(v_sum) # create a time axis in units of µs: x = np.arange(0, wsize, 1) t = tscale*x t_matrix = np.repeat(t[np.newaxis,:], V.size/wsize, 0) # Note: if max_evts != -1, we won't load in all events in the dataset n_events = int(v_matrix_all_ch[0].shape[0]) if n_events == 0: break # perform baseline subtraction for full event (separate from pulse-level baseline subtraction): baseline_start = int(0./tscale) baseline_end = np.min((int(wsize*0.2), 1000)) # baseline subtracted (bls) waveforms saved in this matrix: v_bls_matrix_all_ch = np.zeros( np.shape(v_matrix_all_ch), dtype=array_dtype) # dims are (chan #, evt #, sample #) #t_end_wfm_fill = time.time() #print("Time to fill all waveform arrays: ", t_end_wfm_fill - t_end_load) #print("Events to process: ",n_events) for i in range(0, n_events): sum_baseline = np.mean( v_matrix_all_ch[-1][i,baseline_start:baseline_end] ) #avg ~us, avoiding trigger baselines = [ np.mean( ch_j[i,baseline_start:baseline_end] ) for ch_j in v_matrix_all_ch ] sum_data = v_matrix_all_ch[-1][i,:] - sum_baseline ch_data = [ch_j[i,:]-baseline_j for (ch_j,baseline_j) in zip(v_matrix_all_ch,baselines)] v_bls_matrix_all_ch[:,i,:] = ch_data # ================================================================== # ================================================================== # now setup for pulse finding on the baseline-subtracted sum waveform #check mark #print("Running pulse finder on {:d} events...".format(n_events)) # use for coloring pulses pulse_class_colors = np.array(['blue', 'green', 'red', 'magenta', 'darkorange']) pulse_class_labels = np.array(['Other', 'S1-like LXe', 'S1-like gas', 'S2-like', 'Merged S1/S2']) pc_legend_handles=[] for class_ind in range(len(pulse_class_labels)): pc_legend_handles.append(mpl.patches.Patch(color=pulse_class_colors[class_ind], label=str(class_ind)+": "+pulse_class_labels[class_ind])) for i in range(j*block_size, j*block_size+n_events): if (i)%2000==0: print("Event #",i) # Find pulse locations; other quantities for pf tuning/debugging start_times, end_times, peaks, data_conv, properties = pf.findPulses( v_bls_matrix_all_ch[-1,i-j*block_size,:], max_pulses , SPEMode=False) # Sort pulses by start times, not areas startinds = np.argsort(start_times) n_pulses[i] = len(start_times) if (n_pulses[i] < 1): #print("No pulses found for event {0}; skipping".format(i)) empty_evt_ind[i] = i #continue for m in startinds: if m >= max_pulses: continue p_start[i,m] = start_times[m] p_end[i,m] = end_times[m] # Individual channel pulse locations, in case you want this info # Can't just ":" the the first index in data, findPulses doesn't like it, so have to loop #for j in range(n_channels-1): # start_times_ch, end_times_ch, peaks_ch, data_conv_ch, properties_ch = pf.findPulses( v_bls_matrix_all_ch[j,i,:], max_pulses ) # Sorting by start times from the sum of channels, not each individual channel # for k in startinds: # if k >= len(start_times_ch): # continue # p_start_ch[i,k,j] = start_times_ch[k] # p_end_ch[i,k,j] = end_times_ch[k] # More precisely estimate baselines immediately before each pulse baselines_precise = pq.GetBaselines(p_start[i,:n_pulses[i]], p_end[i,:n_pulses[i]], v_bls_matrix_all_ch[:,i-j*block_size,:]) # Calculate interesting quantities, only for pulses that were found for pp in range(n_pulses[i]): # subtract out more precise estimate of baseline for better RQ estimates baselines_pulse = baselines_precise[pp] # array of baselines per channel, for this pulse v_pulse_bls = np.array([ch_j - baseline_j for (ch_j, baseline_j) in zip(v_bls_matrix_all_ch[:,i-j*block_size,:], baselines_pulse)]) # Version w/o pulse-level baseline subtraction #v_pulse_bls = v_bls_matrix_all_ch[:,i-j*block_size,:] # copied from above, for reference #sum_data = v_matrix_all_ch[-1][i, :] - sum_baseline #ch_data = [ch_j[i, :] - baseline_j for (ch_j, baseline_j) in zip(v_matrix_all_ch, baselines)] # Area, max & min heights, width, pulse mean & rms p_area[i,pp] = pq.GetPulseArea(p_start[i,pp], p_end[i,pp], v_pulse_bls[-1] ) p_max_height[i,pp] = pq.GetPulseMaxHeight(p_start[i,pp], p_end[i,pp], v_pulse_bls[-1] ) p_min_height[i,pp] = pq.GetPulseMinHeight(p_start[i,pp], p_end[i,pp], v_pulse_bls[-1] ) p_width[i,pp] = p_end[i,pp] - p_start[i,pp] #(p_mean_time[i,pp], p_rms_time[i,pp]) = pq.GetPulseMeanAndRMS(p_start[i,pp], p_end[i,pp], v_bls_matrix_all_ch[-1,i,:]) # Area and height fractions (p_afs_2l[i,pp], p_afs_1[i,pp], p_afs_25[i,pp], p_afs_50[i,pp], p_afs_75[i,pp], p_afs_99[i,pp]) = pq.GetAreaFraction(p_start[i,pp], p_end[i,pp], v_pulse_bls[-1] ) (p_hfs_10l[i,pp], p_hfs_50l[i,pp], p_hfs_10r[i,pp], p_hfs_50r[i,pp]) = pq.GetHeightFractionSamples(p_start[i,pp], p_end[i,pp], v_pulse_bls[-1] ) # Areas for individual channels and top bottom p_area_ch[i,pp,:] = pq.GetPulseAreaChannel(p_start[i,pp], p_end[i,pp], v_pulse_bls ) p_area_ch_frac[i,pp,:] = p_area_ch[i,pp,:]/p_area[i,pp] p_area_top[i,pp] = sum(p_area_ch[i,pp,top_channels]) p_area_bottom[i,pp] = sum(p_area_ch[i,pp,bottom_channels]) p_tba[i, pp] = (p_area_top[i, pp] - p_area_bottom[i, pp]) / (p_area_top[i, pp] + p_area_bottom[i, pp]) center_top_x[i,pp] = (p_area_ch[i,pp,1]+p_area_ch[i,pp,3]-p_area_ch[i,pp,0]-p_area_ch[i,pp,2])/p_area_top[i,pp] center_top_y[i,pp] = (p_area_ch[i,pp,0]+p_area_ch[i,pp,1]-p_area_ch[i,pp,2]-p_area_ch[i,pp,3])/p_area_top[i,pp] center_bot_x[i,pp] = (p_area_ch[i,pp,5]+p_area_ch[i,pp,7]-p_area_ch[i,pp,4]-p_area_ch[i,pp,6])/p_area_bottom[i,pp] center_bot_y[i,pp] = (p_area_ch[i,pp,4]+p_area_ch[i,pp,5]-p_area_ch[i,pp,6]-p_area_ch[i,pp,7])/p_area_bottom[i,pp] # Pulse classifier, work in progress p_class[i,:] = pc.ClassifyPulses(p_tba[i, :], (p_afs_50[i, :]-p_afs_2l[i, :])*tscale, n_pulses[i], p_area[i,:]) # Event level analysis. Look at events with both S1 and S2. index_s1 = (p_class[i,:] == 1) + (p_class[i,:] == 2) # S1's index_s2 = (p_class[i,:] == 3) + (p_class[i,:] == 4) # S2's n_s1[i] = np.sum(index_s1) n_s2[i] = np.sum(index_s2) if n_s1[i] > 0: sum_s1_area[i] = np.sum(p_area[i, index_s1]) if n_s2[i] > 0: sum_s2_area[i] = np.sum(p_area[i, index_s2]) if n_s1[i] == 1: if n_s2[i] == 1: drift_Time[i] = tscale*(p_start[i, np.argmax(index_s2)] - p_start[i, np.argmax(index_s1)]) drift_Time_AS[i] = tscale*(p_start[i, np.argmax(index_s2)] - p_start[i, np.argmax(index_s1)]) if n_s2[i] > 1: s1_before_s2[i] = np.argmax(index_s1) < np.argmax(index_s2) drift_Time_AS[i] = tscale*(p_start[i, np.argmax(index_s2)] - p_start[i, np.argmax(index_s1)]) #For multi-scatter events. if drift_Time[i]>0: n_golden += 1 # ============================================================= # draw the waveform and the pulse bounds found # Code to allow skipping to another event index for plotting plot_event_ind = i try: plot_event_ind = int(inn) if plot_event_ind < i: inn = '' plot_event_ind = i print("Can't go backwards! Continuing to next event.") except ValueError: plot_event_ind = i # Condition to plot now includes this rise time calc, not necessary riseTimeCondition = ((p_afs_50[i,:n_pulses[i]]-p_afs_2l[i,:n_pulses[i]] )*tscale < 0.6)*((p_afs_50[i,:n_pulses[i]]-p_afs_2l[i,:n_pulses[i]] )*tscale > 0.2) po_test = np.any((p_area[i,:]>5.0e4)*((p_afs_50[i,:]-p_afs_2l[i,:] )*tscale<1.0)) # Condition to skip the individual plotting, hand scan condition #plotyn = drift_Time[i]<2 and drift_Time[i]>0 and np.any((p_tba[i,:]>-0.75)*(p_tba[i,:]<-0.25)*(p_area[i,:]<3000)*(p_area[i,:]>1400))#np.any((p_tba[i,:]>-0.91)*(p_tba[i,:]<-0.82)*(p_area[i,:]<2800)*(p_area[i,:]>1000))# True#np.any(p_class[i,:]==4)#False#np.any(p_area[i,:]>1000) and #plotyn = drift_Time[i]>2.5 and (center_bot_y[i,0]**2+center_bot_x[i,0]**2) <0.1 plotyn = drift_Time[i]>1 #np.any((p_class[i,:] == 3) + (p_class[i,:] == 4))#np.any((p_tba[i,:]>-0.75)*(p_tba[i,:]<-0.25)*(p_area[i,:]<3000)*(p_area[i,:]>1000)) #plotyn = np.any((p_tba[i,:]>-1)*(p_tba[i,:]<-0.25)*(p_area[i,:]<30000)*(p_area[i,:]>3000))#np.any((np.log10(p_area[i,:])>3.2)*(np.log10(p_area[i,:])<3.4) )#False# # Pulse area condition areaRange = np.sum((p_area[i,:] < 50)*(p_area[i,:] > 5)) if areaRange > 0: dt[i] = abs(p_start[i,1] - p_start[i,0]) # For weird double s1 data weird_areas =[p_area[i,0], p_area[i,1] ] small_weird_areas[i] = min(weird_areas) big_weird_areas[i] = max(weird_areas) # Condition to include a wfm in the average add_wfm = np.any((p_area[i,:]>5000)*(p_tba[i,:]<-0.75))*(n_s1[i]==1)*(n_s2[i]==0) if add_wfm and save_avg_wfm: plotyn = add_wfm # in avg wfm mode, plot the events which will go into the average avg_wfm += v_bls_matrix_all_ch[-1,i-j*block_size,:] n_wfms_summed += 1 # Both S1 and S2 condition s1s2 = (n_s1[i] == 1)*(n_s2[i] == 1) if inn == 's': sys.exit() if not inn == 'q' and plot_event_ind == i and plotyn: fig = pl.figure(1,figsize=(10, 3.5)) pl.rc('xtick', labelsize=10) pl.rc('ytick', labelsize=10) ax = pl.subplot() ch_labels = ['A','B','C','D','E','F','G','H'] ch_colors = [pl.cm.tab10(ii) for ii in range(n_channels)] #pl.plot(t,v_bls_matrix_all_ch[-1,i,:],'blue') #pl.plot( x*tscale, v_bls_matrix_all_ch[-1,i-j*block_size,:],'blue' ) #pl.xlim([0,wsize]) #pl.xlim([0,event_window]) trigger_time_us = 12 # for some reason seems to be consistently closer to 12 than 12.5 pl.xlim([start_times[0]*tscale-3-trigger_time_us,end_times[1]*tscale+1.5-trigger_time_us]) #pl.ylim( [-1, 1.01*np.max(v_bls_matrix_all_ch[-1,i-j*block_size,:])]) pl.ylim( [-1, 1.1*np.max(v_bls_matrix_all_ch[:-1,i-j*block_size,:])]) pl.xlabel('Time ($\mu$s)') #pl.xlabel('Samples') pl.ylabel('phd/sample') #pl.title("Sum, event "+ str(i)) pl.grid(b=True,which='major',color='lightgray',linestyle='--') #pl.legend(handles=pc_legend_handles) dead_channels = [2,7] for i_chan in range(n_channels - 1): if i_chan in dead_channels: continue pl.plot(t-trigger_time_us, v_bls_matrix_all_ch[i_chan, i - j * block_size, :], color=ch_colors[i_chan], label=ch_labels[i_chan]) # pl.plot( x, v_bls_matrix_all_ch[i_chan,i,:],color=ch_colors[i_chan],label=ch_labels[i_chan] ) #pl.xlim([trigger_time_us - 8, trigger_time_us + 8]) # pl.xlim([wsize/2-4000,wsize/2+4000]) #pl.ylim([-5, 3000 / chA_spe_size]) #pl.xlabel('Time (us)') # pl.xlabel('Samples') #pl.ylabel('phd/sample') #pl.legend() for pulse in range(len(start_times)): class_name = "S1" if p_class[i,pulse] == 3 or p_class[i,pulse] == 4: class_name = "S2" ax.axvspan(start_times[pulse] * tscale-trigger_time_us, end_times[pulse] * tscale-trigger_time_us, alpha=0.1, color=pulse_class_colors[p_class[i, pulse]]) ax.text((end_times[pulse]) * tscale+0.1-trigger_time_us, 0.9 * ax.get_ylim()[1], class_name, fontsize=10, color=pulse_class_colors[p_class[i, pulse]]) ax.text((end_times[pulse]) * tscale+0.1-trigger_time_us, 0.84 * ax.get_ylim()[1], 'Area = {:.1f} phd'.format(p_area[i, pulse]), fontsize=10, color=pulse_class_colors[p_class[i, pulse]]) ax.text((end_times[pulse]) * tscale+0.1-trigger_time_us, 0.73 * ax.get_ylim()[1], '$A_{{TB}}$ = {:.1f}'.format(p_tba[i, pulse]), fontsize=10, color=pulse_class_colors[p_class[i, pulse]]) #ax.axhline( 0.276, 0, wsize, linestyle='--', lw=1, color='orange') # Draw drift time w/ arrow arrow_alpha = 0.8 head_length = 0.1 pl.arrow(start_times[0] * tscale-trigger_time_us, 0.5 * ax.get_ylim()[1], drift_Time[i]-head_length, 0, head_width=1.2, head_length=head_length, width=0.05, color='b', alpha=arrow_alpha) ax.text(start_times[0] * tscale-trigger_time_us + drift_Time[i]/5, 0.57 * ax.get_ylim()[1], r'Drift time={:.1f} $\mu$s'.format(drift_Time[i]), fontsize=10, color='b') # Create a set of inset Axes: these should fill the bounding box allocated to # them. from mpl_toolkits.axes_grid.inset_locator import (inset_axes, InsetPosition, mark_inset) ax2 = pl.axes([0, 0, 1, 1]) # Manually set the position and relative size of the inset axes within ax1 ip = InsetPosition(ax, [0.05, 0.43, 0.25, 0.5]) ax2.set_axes_locator(ip) #ax2.set_ylabel('phd/sample') #ax2.set_xlabel('Time (us)') # Mark the region corresponding to the inset axes on ax1 and draw lines # in grey linking the two axes. mark_inset(ax, ax2, loc1=1, loc2=3, fc="none", ec='0.5') ax2.grid(b=True,which='major',color='lightgray',linestyle='--') # Plot data in inset inset_start = start_times[0] inset_end = end_times[0] for i_chan in range(n_channels - 1): if i_chan in dead_channels: continue ax2.plot(t[inset_start:inset_end]-trigger_time_us, v_bls_matrix_all_ch[i_chan, i - j * block_size, inset_start:inset_end], color=ch_colors[i_chan], label=ch_labels[i_chan]) #ax2.plot(t[inset_start:inset_end],v_bls_matrix_all_ch[-1,i,inset_start:inset_end],'blue') #ax2.xlim((start_times[0]*tscale-1,end_times[0]*tscale+1)) #ax2.ylim((start_times[0]*tscale-1,end_times[0]*tscale+1)) #ax2.legend(loc=0) # Debugging of pulse finder debug_pf = False if debug_pf and n_pulses[i]>0: pl.plot(t_matrix[i-j*block_size, :], data_conv, 'red') pl.plot(t_matrix[i-j*block_size, :], np.tile(0., np.size(data_conv)), 'gray') pl.vlines(x=peaks*tscale, ymin=data_conv[peaks] - properties["prominences"], ymax=data_conv[peaks], color="C1") pl.hlines(y=properties["width_heights"], xmin=properties["left_ips"]*tscale, xmax=properties["right_ips"]*tscale, color="C1") #print("pulse heights: ", data_conv[peaks] ) #print("prominences:", properties["prominences"]) pl.draw() pl.show(block=0) inn = input("Press enter to continue, q to stop plotting, evt # to skip to # (forward only)") fig.clf() # end of pulse finding and plotting event loop if save_avg_wfm: avg_wfm /= n_wfms_summed np.savetxt(data_dir+'average_waveform.txt',avg_wfm) print("Average waveform saved") n_events = i t_end = time.time() print("total number of events processed:", n_events) print("Time used: {}".format(t_end-t_start)) print("empty events: {0}".format(np.sum(empty_evt_ind>0))) # pl.hist(empty_evt_ind[empty_evt_ind>0], bins=1000) # pl.xlabel('Empty event index') # pl.show() #create a dictionary with all RQs list_rq = {} list_rq['center_top_x'] = center_top_x list_rq['center_top_y'] = center_top_y list_rq['center_bot_x'] = center_bot_x list_rq['center_bot_y'] = center_bot_y list_rq['n_s1'] = n_s1 list_rq['n_s2'] = n_s2 list_rq['s1_before_s2'] = s1_before_s2 list_rq['n_pulses'] = n_pulses list_rq['n_events'] = n_events list_rq['p_area'] = p_area list_rq['p_class'] = p_class list_rq['drift_Time'] = drift_Time list_rq['drift_Time_AS'] = drift_Time_AS list_rq['p_max_height'] = p_max_height list_rq['p_min_height'] = p_min_height list_rq['p_width'] = p_width list_rq['p_afs_2l'] = p_afs_2l list_rq['p_afs_50'] = p_afs_50 list_rq['p_area_ch'] = p_area_ch list_rq['p_area_ch_frac'] = p_area_ch_frac list_rq['p_area_top'] = p_area_top list_rq['p_area_bottom'] = p_area_bottom list_rq['p_tba'] = p_tba list_rq['p_start'] = p_start list_rq['p_end'] = p_end list_rq['sum_s1_area'] = sum_s1_area list_rq['sum_s2_area'] = sum_s2_area #list_rq[''] = #add more rq #remove zeros in the end of each RQ array. for rq in list_rq.keys(): if rq != 'n_events': list_rq[rq] = list_rq[rq][:n_events] rq = open(data_dir + "rq.npz",'wb') np.savez(rq, **list_rq) rq.close()
# Now colour in the gradient to indicate the magnitude of delta. Unfortunately, there is no easy built-in function to do this, so we essentially have to colour each slice of data by hand: for i in range(len(delta_c_for_gradient) - 1): plt.fill_between([beta_delta_c_gradient[i], beta_delta_c_gradient[i + 1]], [ example_curve_cluster_for_gradient[i], example_curve_cluster_for_gradient[i + 1] ], [thermometer_example_C, thermometer_example_C], color=delta_cluster_cmap( normalize(delta_c_for_gradient[i])), zorder=-2) ## Set up inset axes to place the colorbars on the thermometry example plot in nice positions # colorbar_c_location = [0.35,0.1,0.22,0.03] colorbar_c_location = [0.05, 0.1, 0.22, 0.03] col_c_ax = axes([0, 0, 1, 1], frameon=False, label='c') col_c_ip = InsetPosition(thermometry_example_ax, colorbar_c_location) col_c_ax.set_axes_locator(col_c_ip) ## Now add a colorbar to show the magnitude of delta: fakefig_c = figure('Colorbar C') cbar_c_show = imshow(array([[0, delta_max]]), cmap=delta_cluster_cmap) sca(thermometry_example_ax) cb_c = colorbar(cbar_c_show, cax=col_c_ax, ticks=[0, delta_max], orientation="horizontal") cb_c.outline.set_linewidth(0.5) cb_c.ax.set_xticklabels(cb_c.ax.get_xticklabels(), fontsize=5, y=1) text(colorbar_c_location[0] + 0.5 * colorbar_c_location[2], colorbar_c_location[1] + 2 * colorbar_c_location[3],
def plotCasesAndDeathsTwoPanes(self, window): # Compute the moving average but just don't just truncate dailyCasesMovingAverage = self.convolutionMovingAverage( self.dailyCases, window) dailyDeathsMovingAverage = self.convolutionMovingAverage( self.dailyDeaths, window) # Start figure fig, ax = plt.subplots(2, 1, constrained_layout=True, figsize=(5, 6), dpi=300) ax[0].plot(self.dates, self.cumulativeCases, '-', c='blue', lw=1.5) ax[0].plot(self.dates, self.cumulativeCases, '.', c='blue', lw=1.5) ax[0].set_title(self.county + ", " + self.state + " Cumulative Cases and Cases/Day", fontsize=8) ax[0].set_ylabel("Cumulative Cases", fontsize=8) axDaily0 = ax[0].twinx() axDaily0.bar(self.dates, self.dailyCases, color='orange', align='edge') axDaily0.plot(self.dates, dailyCasesMovingAverage, c='grey') axDaily0.set_ylabel("Daily Cases", fontsize=8) # Custom legend convolutionLabel = str(window) + " Day Convolution" legendElements = [matplotlib.lines.Line2D([0], [0], color='b', marker='.', lw=1.5, label='Cumulative Cases'), \ matplotlib.lines.Line2D([0], [0], color='grey', lw=1.5, label=convolutionLabel)] ax[0].legend(handles=legendElements, loc=2, fontsize=8) # Common pane format options self.setTwoPaneFormatPerPane(ax[0], axDaily0) if self.insertType: # Optional inset with log daily data axInset = plt.axes([0, 0, 1, 1]) if self.insertType == 'right': ip = InsetPosition(ax[0], [0.40, 0.25, 0.4, 0.4]) elif self.insertType == 'left': print("'left' is not actually supported") sys.exit() axInset.set_axes_locator(ip) axInset.bar(self.dates[-30:], self.dailyCases[-30:], color='orange', align='edge') axInset.plot(self.dates[-30:], dailyCasesMovingAverage[-30:], c='grey') # Will use these to smooth out the x data for any called county locator = mdates.AutoDateLocator(maxticks=6) formatter = mdates.ConciseDateFormatter(locator) # Apply formatting after second axis axInset.xaxis.set_major_locator(locator) axInset.xaxis.set_major_formatter(formatter) # Only need to set the xlim on the second axis newDateLims = [self.dates[-30], self.dates[-1]] axInset.set_xlim(newDateLims) # NYTimes data is sometimes a little ridiculous axInset.set_ylim(bottom=0) axInset.tick_params(labelsize=8) # Ax[1] is deaths ax[1].plot(self.dates, self.cumulativeDeaths, '-', c='blue', lw=1.5) ax[1].plot(self.dates, self.cumulativeDeaths, '.', c='blue', lw=1.5) ax[1].set_title(self.county + ", " + self.state + " Cumulative Deaths and Deaths/Day", fontsize=8) ax[1].set_ylabel("Cumulative Deaths", fontsize=8) axDaily1 = ax[1].twinx() axDaily1.bar(self.dates, self.dailyDeaths, color='orange', align='edge') axDaily1.plot(self.dates, dailyDeathsMovingAverage, c='grey') axDaily1.set_ylabel("Daily Deaths", fontsize=8) # Custom legend convolutionLabel = str(window) + " Day Convolution" legendElements = [ matplotlib.lines.Line2D([0], [0], color='b', marker='.', lw=1.5, label='Cumulative Deaths'), matplotlib.lines.Line2D([0], [0], color='grey', lw=1.5, label=convolutionLabel) ] ax[1].legend(handles=legendElements, fontsize=8) # Common pane format options self.setTwoPaneFormatPerPane(ax[1], axDaily1) # Save a figure if not os.path.exists('images'): os.makedirs('images') nameOfFigure = 'images/' + self.county + "-" + self.state + "-" + self.dataType + ".png" plt.savefig(nameOfFigure)
def plot_profile_with_subplot(ax, binn, val, disp, limx, limy, limxsp, limysp, alabels, llabels, snap, s1, s2, save): ax.fill_between(binn, val - disp, val + disp, edgecolor='grey', hatch='//////', facecolor='none', alpha=0.3, label=llabels[0]) ax.plot(binn, val, c='navy', lw=1, marker='o', ms=3, mfc='white', label=llabels[1], mec='navy') ax.set_xlabel(alabels[0]) ax.set_ylabel(alabels[1]) ax.set_xlim(limx[0], limx[1]) ax.set_ylim(limy[0], limy[1]) xticks, yticks = ax.xaxis.get_major_ticks(), ax.yaxis.get_major_ticks() xticks[0].label1.set_visible(False) yticks[0].label1.set_visible(False) xticks[-1].label1.set_visible(False) yticks[-1].label1.set_visible(False) ax.minorticks_on() time = snap[9::] ax.text(0.87, 0.05, "t=" + time, ha='center', va='center', transform=ax.transAxes, color="black") ax.legend(loc='upper left', frameon=False, ncol=1, scatterpoints=1, borderpad=0.1, labelspacing=0.2, handletextpad=0.1) ax.ticklabel_format(style='sci', axis='y', scilimits=(0, 0)) ax_sp = plt.axes([0, 0, 1, 1]) ip = InsetPosition(ax, [0.45, 0.65, 0.5, 0.30]) ax_sp.set_axes_locator(ip) ax_sp.plot(binn, val, c='navy', lw=1, marker='o', ms=3, mfc='white', mec='navy') ax_sp.set_xlim(limxsp[0], limxsp[1]) ax_sp.set_ylim(limysp[0], limysp[1]) xticks_sp, yticks_sp = ax_sp.xaxis.get_major_ticks( ), ax_sp.yaxis.get_major_ticks() visible_ticks(xticks_sp, yticks_sp) ax_sp.ticklabel_format(style='sci', axis='y', scilimits=(0, 0)) ax_sp.tick_params(labelsize=10) ax_sp.minorticks_on() if save == 1: plt.savefig(s1 + '.pdf', dpi=100, bbox_inches='tight') plt.savefig(s2 + '.png', dpi=100, bbox_inches='tight') plt.show()
def plot_time_series(specify_sequence): '''Generates a figure with graphs of data vs time for a specified sequence of experiments, corresponding to a fixed grid width.''' print "Working on sequence", specify_sequence ## Get a dataframe containing only the data for the current grid sequences = [os.path.split(path)[1][0:15] for path in full_df['filepath']] df = full_df[[(sequence == specify_sequence) for sequence in sequences]] ## Throw out rejected shots df = df[df['review_vortex_locations', 'Good'] == True] grid_radius = df['vortex_beam_radius'][0] * dmd_pixel_size grid_radius_micron = grid_radius * 1e6 ## Set up worksheet for data saving worksheet = workbook.add_worksheet('%s micron grid' % grid_radius_micron) worksheet.write(0, 0, 'Time series data for %s micron grid' % grid_radius_micron, bold) for head_i, heading in enumerate(data_table_headings): worksheet.write(1, head_i, heading, bold) worksheet_spectra = workbook.add_worksheet('%s micron grid Spectra' % grid_radius_micron) worksheet_spectra.write( 0, 0, 'Kinetic energy spectra for %s micron grid' % grid_radius_micron, bold) worksheet_spectra.write(1, 0, 'Hold time:', boldshaded) worksheet_spectra.write(2, 0, 'k vector', bold) ### Set up the figure windows and axes for this grid ### fig = figure('dynamics %s' % specify_sequence, figsize=(4.75, 2.8)) ## We use gridspec to arrange the subfigures ## there are two with the same splitting, so that we can control padding better for the larger log-scale graph gs = GridSpec(5, 3, width_ratios=[2, 1, 1]) gs_log = GridSpec(5, 3, width_ratios=[2, 1, 1]) ## Create an axis for each graph class_ax = fig.add_subplot(gs[0, 0]) corr_ax = fig.add_subplot(gs[1, 0]) dm_ax = fig.add_subplot(gs[2, 0]) temp_ax = fig.add_subplot(gs[3, 0]) e_ax = fig.add_subplot(gs[4, 0]) spec_ax = fig.add_subplot(gs_log[:3, 1:3]) logN_ax = fig.add_subplot(gs_log[3:, 1]) logL_ax = fig.add_subplot(gs_log[3:, 2]) ## Set up an inset axis to place the colorbar on the energy spectrum plot in a nice position colorbar_location = [0.73, 0.8, 0.22, 0.03] col_ax = axes([0, 0, 1, 1], frameon=False) col_ip = InsetPosition(spec_ax, colorbar_location) col_ax.set_axes_locator(col_ip) ## Calculations for where to place the inset figure on the energy spectrum such that the x-axis lines up espec_x_min = 2e-2 espec_x_max = 5 espec_inset_x_min = 3.5e-2 espec_inset_x_max = 1.25 figw = log(espec_x_max) - log(espec_x_min) insetoffset = (log(espec_inset_x_min) - log(espec_x_min)) / figw insetw = (log(espec_inset_x_max) - log(espec_inset_x_min)) / figw delta_e_location = [insetoffset, .05, insetw, 0.35] delta_e_ax = axes([0, 0, 1, 1]) delta_e_ip = InsetPosition(spec_ax, delta_e_location) delta_e_ax.set_axes_locator(delta_e_ip) ## An iterator to use to cycle through colours on the energy spectra e_spec_color = iter(cm.inferno_r(np.linspace(0.1, 1, 10))) ### Create empty lists in which we can later store the average value and the uncertainty of each measurement at each hold time ## Classified vortex numbers avg_N_c = [] avg_u_N_c = [] avg_N_d = [] avg_u_N_d = [] avg_N_f = [] avg_u_N_f = [] avg_N_v = [] avg_u_N_v = [] ## Dipole moment avg_d = [] avg_u_d = [] ## Total incompressible kinetic energy per vortex avg_en = [] avg_u_en = [] ## Correlation function avg_c1 = [] avg_u_c1 = [] ## Mean nearest-neighbor vortex distance avg_mean_nearest_vortex = [] u_avg_mean_nearest_vortex = [] ## and of course, we need a time vector t_vals = [] ## Now, we group the dataframe by hold time, and for each time, add the time to t_vals, ## calculate the mean and sem of each measurement, and add them to their appropriate lists: spreadsheet_row = 0 for hold_time, group in df.groupby('vortex_spoon_wait_time'): t_vals.append(hold_time) N_v = group[('vortex_signs_classification_and_statistics', 'N_v')] avg_N_v.append(mean(N_v)) avg_u_N_v.append(sem(N_v)) ## We want the fractional populations, so before averaging, ## each absolute number of clusters has to be divided by the ## total number of vortices in that shot. N_c = group[('vortex_signs_classification_and_statistics', 'N_c')] / N_v avg_N_c.append(mean(N_c)) avg_u_N_c.append(sem(N_c)) N_d = group[('vortex_signs_classification_and_statistics', 'N_d')] / N_v avg_N_d.append(mean(N_d)) avg_u_N_d.append(sem(N_d)) N_f = group[('vortex_signs_classification_and_statistics', 'N_f')] / N_v avg_N_f.append(mean(N_f)) avg_u_N_f.append(sem(N_f)) D = group[('vortex_signs_classification_and_statistics', 'D')] avg_d.append(mean(D)) avg_u_d.append(sem(D)) eN = group[('energy_spectra', 'KE_per_vortex')] avg_en.append(mean(eN)) avg_u_en.append(sem(eN)) C_1 = group[('vortex_signs_classification_and_statistics', 'C_1')] avg_c1.append(mean(C_1)) avg_u_c1.append(sem(C_1)) mean_nearest_vortex = group[( 'vortex_signs_classification_and_statistics', 'mean_nearest_vortex')] avg_mean_nearest_vortex.append(mean(mean_nearest_vortex)) u_avg_mean_nearest_vortex.append(sem(mean_nearest_vortex)) ### Kinetic energy spectra ### ## We make a list containing arrays with the energy spectra of each shot, for this current hold time e_specs = [] for path in group['filepath']: run = lyse.Run(path, no_write=True) e_spec = run.get_result_array('energy_spectra', 'KE_per_vortex_spec') k_vec = run.get_result_array('energy_spectra', 'k_vec') e_specs.append(e_spec) ## Now take that list of arrays and make it an array itself, so that we can take its average and sem across each shot at each k-vector e_specs = array(e_specs) av_e_spec = mean(e_specs, axis=0) u_e_spec = sem(e_specs, axis=0) ## We're going to plot this in the loop, so that we don't have to worry about storing these values for each time point independantly sca(spec_ax) ## Get the colour to use in this loop from the iterator col_now = next(e_spec_color) loglog(k_vec, av_e_spec, c=col_now, label=r"$E(k)$, t = %s" % hold_time) ## We want to plot the difference from t=0.5 in the inset, so on the first loop, we will get the t=0.5 data, ## then subsequent loops will subtract this from the current time's data to get the difference. if hold_time == 0.5: initial_spec = av_e_spec delta_e_ax.plot(k_vec, zeros(shape(initial_spec)), c=col_now, label=r"$E(k)$, t = %s" % hold_time) else: delta_spec = av_e_spec - initial_spec delta_e_ax.plot(k_vec, delta_spec * 1e7, c=col_now, label=r"$E(k)$, t = %s" % hold_time) ## Add energy spectra data for this time point to the spreadsheet: for k_vec_i in range(len(k_vec)): if hold_time == 0.5: worksheet_spectra.write(k_vec_i + 3, 0, k_vec[k_vec_i]) worksheet_spectra.write(k_vec_i + 3, 2 * spreadsheet_row + 1, av_e_spec[k_vec_i], leftborder) worksheet_spectra.write(k_vec_i + 3, 2 * spreadsheet_row + 2, u_e_spec[k_vec_i], rightborder) worksheet_spectra.merge_range(1, 2 * spreadsheet_row + 1, 1, 2 * spreadsheet_row + 2, hold_time, shaded) worksheet_spectra.write(2, 2 * spreadsheet_row + 1, 'E(k)', boldleftborder) worksheet_spectra.write(2, 2 * spreadsheet_row + 2, 'sem(E(k))', boldrightborder) spreadsheet_row += 1 ##### END OF LOOP OVER TIME ##### ### Now, calculate the temperature at each hold time, based on the fraction of clusters and dipoles, and the total vortex number. beta_measured = thermometer_cdN(array(avg_N_c), array(avg_N_d), array(avg_N_v)) beta_upper_error = thermometer_cdN( array(avg_N_c) + array(avg_u_N_c), array(avg_N_d) - array(avg_u_N_d), array(avg_N_v)) beta_lower_error = thermometer_cdN( array(avg_N_c) - array(avg_u_N_c), array(avg_N_d) + array(avg_u_N_d), array(avg_N_v)) ### Now we have everything that we want to plot! ### ## First save it to the spreadsheet for time_i, hold_time in enumerate(t_vals): worksheet.write(time_i + 2, 0, hold_time) worksheet.write(time_i + 2, 1, avg_N_c[time_i]) worksheet.write(time_i + 2, 2, avg_u_N_c[time_i]) worksheet.write(time_i + 2, 3, avg_N_d[time_i]) worksheet.write(time_i + 2, 4, avg_u_N_d[time_i]) worksheet.write(time_i + 2, 5, avg_N_f[time_i]) worksheet.write(time_i + 2, 6, avg_u_N_f[time_i]) worksheet.write(time_i + 2, 7, avg_c1[time_i]) worksheet.write(time_i + 2, 8, avg_u_c1[time_i]) worksheet.write(time_i + 2, 9, avg_d[time_i]) worksheet.write(time_i + 2, 10, avg_u_d[time_i]) worksheet.write(time_i + 2, 11, beta_measured[time_i]) worksheet.write(time_i + 2, 12, beta_measured[time_i] - beta_upper_error[time_i]) worksheet.write(time_i + 2, 13, beta_lower_error[time_i] - beta_measured[time_i]) worksheet.write(time_i + 2, 14, avg_en[time_i]) worksheet.write(time_i + 2, 15, avg_u_en[time_i]) worksheet.write(time_i + 2, 16, avg_N_v[time_i]) worksheet.write(time_i + 2, 17, avg_u_N_v[time_i]) worksheet.write(time_i + 2, 18, avg_mean_nearest_vortex[time_i]) worksheet.write(time_i + 2, 19, u_avg_mean_nearest_vortex[time_i]) ## Temperature graph sca(temp_ax) temp_ax.errorbar(t_vals, beta_measured, yerr=array([ beta_measured - beta_lower_error, beta_upper_error - beta_measured ]), c='k', mfc='k', fmt="o", ms=5, mew=0, capsize=1, capthick=1, ls='-') temp_ax.axhline(y=0, c='k', ls=':', lw=0.5) temp_ax.invert_yaxis() xlim(0, 5.5) ylabel(r"$\beta$") ## Vortex number graph sca(logN_ax) logN_ax.errorbar(t_vals, avg_N_v, yerr=avg_u_N_v, c="k", fmt="o", ms=5, mew=0, capsize=1, capthick=1) logN_ax.set_xscale('log') logN_ax.set_yscale('log') ylabel("$N_v$") xlabel('Hold time (s)') ### Generate guide-to-eye lines to plot on the vortex number panel ### The values of these lines are chosen for each grid such that the lines are close to the data t_for_lines = linspace(0.4, 6, 12) ## 6.0 if specify_sequence == '20171004T121555': ## 3.5 body tn25 = 15 * t_for_lines**(-2. / 5) # 2 body tn1 = 20 * t_for_lines**(-1.) ## 11.5 elif specify_sequence == '20171006T101525': ## 3.5 body tn25 = 13 * t_for_lines**(-2. / 5) # 2 body tn1 = 30 * t_for_lines**(-1.) ##4.2 elif specify_sequence == '20171004T093812': ## 3.5 body tn25 = 11 * t_for_lines**(-2. / 5) # 2 body tn1 = 15 * t_for_lines**(-1.) ## 9.7 elif specify_sequence == '20171004T144649': ## 3.5 body tn25 = 13 * t_for_lines**(-2. / 5) # 2 body tn1 = 25 * t_for_lines**(-1.) ## 7.9 else: ## 3.5 body tn25 = 14 * t_for_lines**(-2. / 5) # 2 body tn1 = 25 * t_for_lines**(-1.) loglog(t_for_lines, tn25, c='k', lw=0.5, ls='-', zorder=-1) loglog(t_for_lines, tn1, c='k', lw=0.5, ls=':', zorder=-1) xlim(0.4, 6) ylim(3, 25) ## Mean distance graph sca(logL_ax) logL_ax.errorbar(t_vals, avg_mean_nearest_vortex, yerr=u_avg_mean_nearest_vortex, c="k", fmt="o", ms=5, mew=0, capsize=1, capthick=1) logL_ax.set_xscale('log') logL_ax.set_yscale('log') ylabel("$l_v/R_\perp$") xlabel('Hold time (s)') ### Generate guide-to-eye lines to plot on the vortex spacing panel ### The values of these lines are chosen for each grid such that the lines are close to the data ## 6.0 if specify_sequence == '20171004T121555': t12 = 0.22 * t_for_lines**(0.5) t15 = 0.23 * t_for_lines**(1. / 5) ## 11.5 elif specify_sequence == '20171006T101525': t12 = 0.22 * t_for_lines**(0.5) t15 = 0.26 * t_for_lines**(1. / 5) ## 4.2 elif specify_sequence == '20171004T093812': t12 = 0.23 * t_for_lines**(0.5) t15 = 0.27 * t_for_lines**(1. / 5) ## 9.7 elif specify_sequence == '20171004T144649': t12 = 0.22 * t_for_lines**(0.5) t15 = 0.26 * t_for_lines**(1. / 5) ##7.9 else: t12 = 0.2 * t_for_lines**(0.5) t15 = 0.25 * t_for_lines**(1. / 5) loglog(t_for_lines, t12, c='k', lw=0.5, ls=':', label=r'$t^{1/2}$', zorder=-1) loglog(t_for_lines, t15, c='k', lw=0.5, ls='-', label=r'$t^{1/5}$', zorder=-1) xlim(0.4, 6) ylim(0.18, 0.55) ## Classified populations graph sca(class_ax) class_ax.errorbar(t_vals, avg_N_f, yerr=avg_u_N_f, c=colour_free, mec=colour_free, mfc=colour_free, fmt="o", ms=5, mew=0, capsize=1, capthick=1, ls='-', label="Free vortices") class_ax.errorbar(t_vals, avg_N_d, yerr=avg_u_N_d, c=colour_dipole, mec=colour_dipole, mfc=colour_dipole, fmt="o", ms=5, mew=0, capsize=1, capthick=1, ls='-', label="Dipole vortices") class_ax.errorbar(t_vals, avg_N_c, yerr=avg_u_N_c, c=colour_cluster, mec=colour_cluster, mfc=colour_cluster, fmt="o", ms=5, mew=0, capsize=1, capthick=1, ls='-', label="Clustered vortices") ylabel("$p_i$") xlim(0, 5.5) ## Add a legend - this is done manually so that we can squash it down to the smallest possible size leg_cluster = mlines.Line2D([], [], color=colour_cluster, marker='o', ms=5, mew=0, ls='-', label='$p_c$') leg_dipole = mlines.Line2D([], [], color=colour_dipole, marker='o', ms=5, mew=0, ls='-', label='$p_d$') leg_free = mlines.Line2D([], [], color=colour_free, marker='o', ms=5, mew=0, ls='-', label='$p_f$') legend(handles=[leg_cluster, leg_dipole, leg_free], bbox_to_anchor=(0.52, 0.99), ncol=3, borderpad=0, borderaxespad=0, handletextpad=0.2, columnspacing=0.5, handlelength=1, frameon=False, handler_map={ leg_cluster: HandlerLine2D(numpoints=1, marker_pad=0), leg_dipole: HandlerLine2D(numpoints=1, marker_pad=0), leg_free: HandlerLine2D(numpoints=1, marker_pad=0) }) ## Total incompressible kinetic energy graph sca(e_ax) ylabel(r"$E_k/N_v$") e_ax.errorbar(t_vals, avg_en, yerr=avg_u_en, c="k", fmt="o", ls='-', ms=5, mew=0, capsize=1, capthick=1) xlim(0, 5.5) ## Dipole moment graph sca(dm_ax) ylabel('$d/R_\perp$') errorbar(t_vals, avg_d, yerr=avg_u_d, c="k", fmt="o", ls='-', ms=5, mew=0, capsize=1, capthick=1) xlim(0, 5.5) ## Correlation function graph sca(corr_ax) corr_ax.axhline(y=0, c='k', ls=':', lw=0.5) ylabel(r"$C_1$") errorbar(t_vals, avg_c1, yerr=avg_u_c1, c="k", fmt="o", label="$C_1$", ls='-', ms=5, mew=0, capsize=1, capthick=1) xlim(0, 5.5) #### Done plotting the data, now tidy up the figure formatting #### ## Turn off tick labels on the x-axis of the stacked graphs class_ax.xaxis.set_ticklabels([]) temp_ax.xaxis.set_ticklabels([]) corr_ax.xaxis.set_ticklabels([]) dm_ax.xaxis.set_ticklabels([]) class_ax.tick_params(axis='x', which='minor', bottom='off', top="off") temp_ax.tick_params(axis='x', which='minor', bottom='off', top="off") corr_ax.tick_params(axis='x', which='minor', bottom='off', top="off") dm_ax.tick_params(axis='x', which='minor', bottom='off', top="off") e_ax.tick_params(axis='x', which='minor', bottom='off', top="off") ## label positioning common values figlabelx = -0.19 figlabely = 0.68 labelx = -0.15 labely = -0.38 ## Fix classification graph formatting sca(class_ax) ## Add the label class_ax.yaxis.set_label_coords(labelx, 0.5) class_ax.xaxis.set_label_coords(0.5, labely) class_ax.set_title('A', fontdict=blackfont, x=figlabelx, y=figlabely) ## Set the y-axis limits and tick marks depending on the grid (values chosen to best display data and provide sensible tick marks) ## 6.0 if specify_sequence == '20171004T121555': yticks([0.2, 0.4, 0.6]) ylim(0, 0.8) ## 11.5 elif specify_sequence == '20171006T101525': yticks([0.2, 0.4, 0.6]) ylim(0, 0.8) ## 4.2 elif specify_sequence == '20171004T093812': yticks([0.2, 0.4, 0.6]) ylim(0, 0.8) ## 9.7 elif specify_sequence == '20171004T144649': yticks([0.2, 0.4, 0.6]) ylim(0, 0.8) ## 7.9 else: yticks([0.2, 0.4, 0.6]) ylim(0, 0.8) ## Fix correlation function graph formatting sca(corr_ax) ## Add the label corr_ax.yaxis.set_label_coords(labelx, 0.5) corr_ax.xaxis.set_label_coords(0.5, labely) corr_ax.set_title('B', fontdict=blackfont, x=figlabelx, y=figlabely) # since this graph has another on top of it, don't plot the top border, it will rely on the bottom border of the next graph up corr_ax.spines["top"].set_visible(False) ## Set the y-axis limits and tick marks depending on the grid (values chosen to best display data and provide sensible tick marks) ## 9.7 if specify_sequence == '20171004T144649': yticks([0, 0.2, 0.4]) ## 7.9 elif specify_sequence == '20171005T090729': yticks([-0.2, 0, 0.2, 0.4]) ## 11.5 elif specify_sequence == '20171006T101525': yticks([0.1, 0.3, 0.5]) ## 4.2 elif specify_sequence == '20171004T093812': yticks([-0.6, -0.4, -0.2, 0, 0.2]) ## 6.0 else: ylim(-0.3, 0.35) yticks([-0.2, 0, 0.2]) ## Fix dipole moment graph formatting sca(dm_ax) ## Add the label dm_ax.yaxis.set_label_coords(labelx, 0.5) dm_ax.xaxis.set_label_coords(0.5, labely) dm_ax.set_title('C', fontdict=blackfont, x=figlabelx, y=figlabely) # since this graph has another on top of it, don't plot the top border, it will rely on the bottom border of the next graph up dm_ax.spines["top"].set_visible(False) ## Set the y-axis limits and tick marks depending on the grid (values chosen to best display data and provide sensible tick marks) # 6.0 if specify_sequence == '20171004T121555': yticks([0.1, 0.2, 0.3]) ylim(0.05, 0.35) ## 11.5 elif specify_sequence == '20171006T101525': ylim(0.18, 0.38) yticks([0.2, 0.25, 0.3, 0.35]) # 4.2 elif specify_sequence == '20171004T093812': yticks([0.1, 0.2, 0.3]) ## 9.7 elif specify_sequence == '20171004T144649': yticks([0.22, 0.26, 0.3]) # 7.9 else: yticks([0.15, 0.2, 0.25, 0.3]) ## Fix temperature graph formatting sca(temp_ax) ## Add the label temp_ax.yaxis.set_label_coords(labelx, 0.5) temp_ax.xaxis.set_label_coords(0.5, labely) temp_ax.set_title('D', fontdict=blackfont, x=figlabelx, y=figlabely) # since this graph has another on top of it, don't plot the top border, it will rely on the bottom border of the next graph up temp_ax.spines["top"].set_visible(False) ## Set the y-axis limits and tick marks depending on the grid (values chosen to best display data and provide sensible tick marks) # 7.9 micron if specify_sequence == '20171005T090729': yticks([0, -0.2, -0.4, -0.6]) # 11.5 micron elif specify_sequence == '20171006T101525': ylim(-0.18, -0.78) yticks([-0.3, -0.5, -0.7]) # 4.2 micron elif specify_sequence == '20171004T093812': yticks([0.2, 0, -0.2, -0.4, -0.6]) ylim(0.4, -0.7) # 9.7 micron elif specify_sequence == '20171004T144649': ylim(-0.1, -0.75) yticks([-0.2, -0.4, -0.6]) # 6.0 micron else: ylim(0.2, -0.65) yticks([0.1, -0.1, -0.3, -0.5]) ## Fix energy graph formatting sca(e_ax) ## Add the label e_ax.yaxis.set_label_coords(labelx, 0.5) e_ax.xaxis.set_label_coords(0.5, labely) e_ax.set_title('E', fontdict=blackfont, x=figlabelx, y=figlabely) # since this graph has another on top of it, don't plot the top border, it will rely on the bottom border of the next graph up e_ax.spines["top"].set_visible(False) # also set the x-label for this graph, since it's on the bottom of the stack xlabel("Hold time (s)") ## Set the y-axis limits and tick marks depending on the grid (values chosen to best display data and provide sensible tick marks) ## 6.0 if specify_sequence == '20171004T121555': ylim(2.25, 3.35) yticks([2.4, 2.6, 2.8, 3, 3.2]) ## 7.9 elif specify_sequence == '20171005T090729': yticks([2.8, 3.0, 3.2]) ## 4.2 elif specify_sequence == '20171004T093812': yticks([2.4, 2.8, 3.2]) ## 11.5 elif specify_sequence == '20171006T101525': yticks([3.0, 3.2, 3.4, 3.6]) ## 9.7 else: yticks([3, 3.2, 3.4]) #### Now fix the spines on the stacked left-hand graphs spine_left_value = -0.8 class_ax.spines['top'].set_bounds(spine_left_value, class_ax.viewLim.intervalx[1]) class_ax.spines['bottom'].set_bounds(spine_left_value, class_ax.viewLim.intervalx[1]) corr_ax.spines['bottom'].set_bounds(spine_left_value, corr_ax.viewLim.intervalx[1]) dm_ax.spines['bottom'].set_bounds(spine_left_value, dm_ax.viewLim.intervalx[1]) temp_ax.spines['bottom'].set_bounds(spine_left_value, temp_ax.viewLim.intervalx[1]) e_ax.spines['bottom'].set_bounds(spine_left_value, e_ax.viewLim.intervalx[1]) ## Fix energy spectrum graph formatting sca(spec_ax) ylabel(r'$E(k)/N_v$') xlabel(r'$k\xi$') ## Add vertical lines: ## Note, k_vec is in units of xi # k*xi = 1 plt.axvline(x=1, c='0.5', ls=':', zorder=-3) # system size k_sys = xi * 2 * pi / (circ_radius * pixel_size * 2) plt.axvline(x=k_sys, c='0.5', ls='-', zorder=-3) # grid size k_grid_radius = xi * pi / grid_radius plt.axvline(x=k_grid_radius, c='0.5', ls='--', zorder=-3) ## Generate guides to the eye at power-law scalings minus1 = 2e-7 * k_vec**(-1) minus3 = 2e-7 * k_vec**(-3) minus53 = 1.55e-7 * k_vec**(-5. / 3) plt.loglog(k_vec, minus1, c='k', ls='-', lw=0.5, zorder=-3) plt.loglog(k_vec, minus3, c='k', ls=':', lw=0.5, zorder=-3) plt.loglog(k_vec, minus53, c='k', ls='--', lw=0.5, zorder=-3) ## Generate a temporary figure environment for using to generate a colorbar for the energy spectra. fakefig = figure('Colorbar') cbar_show = imshow(array([[0, 5]]), cmap="inferno_r") ## Go back to the spectrum axis (creating the figure above will have changed the current axis) and create the colorbar, based on the above imshow sca(spec_ax) cb = colorbar(cbar_show, cax=col_ax, ticks=[0, 5], orientation="horizontal") cb.outline.set_linewidth(0.5) cb.ax.set_xticklabels(cb.ax.get_xticklabels(), fontsize=5, y=1) plt.text(colorbar_location[0] + 0.5 * colorbar_location[2], colorbar_location[1] + 2 * colorbar_location[3], "Hold time (s)", fontsize=5, ha='center', transform=spec_ax.transAxes) ## Now format the figure itself xlim(espec_x_min, espec_x_max) ylim(1e-9, 4e-6) yticks([1e-8, 1e-7, 1e-6]) spec_ax.yaxis.set_label_coords(-0.1, 0.5) spec_ax.xaxis.set_label_coords(0.5, -0.1) spec_ax.set_title('F', fontdict=blackfont, x=-0.14, y=0.88) spec_ax.tick_params(axis='y', direction='in', pad=1) spec_ax.tick_params(axis='x', direction='in', pad=1.5) ## Fix vortex number graph formatting sca(logN_ax) logN_ax.yaxis.set_label_coords(-0.22, 0.5) logN_ax.xaxis.set_label_coords(0.5, -0.24) logN_ax.set_title('G', fontdict=blackfont, x=-0.32, y=0.8) logN_ax.xaxis.set_major_formatter(ScalarFormatter()) logN_ax.yaxis.set_major_formatter(ScalarFormatter()) yticks([4, 6, 10, 20]) xticks([0.5, 1, 2, 5]) ## Fix vortex spacing graph formatting sca(logL_ax) logL_ax.yaxis.set_label_coords(-0.22, 0.5) logL_ax.xaxis.set_label_coords(0.5, -0.24) logL_ax.set_title('H', fontdict=blackfont, x=-0.32, y=0.8) logL_ax.xaxis.set_major_formatter(ScalarFormatter()) logL_ax.yaxis.set_major_formatter(ScalarFormatter()) yticks([0.2, 0.3, 0.4, 0.5]) xticks([0.5, 1, 2, 5]) ## Fix the inset in the energy spectrum graph's formatting sca(delta_e_ax) title(r'$\Delta E(k)/N_v \times 10^7$', fontdict=tinyfont, x=0.2, y=0.9) xlim(espec_inset_x_min, espec_inset_x_max) delta_e_ax.set_xscale("log", nonposx='clip') locator_params(axis='y', nbins=4) delta_e_ax.tick_params(axis='both', length=2) delta_e_ax.tick_params(axis='x', which='minor', length=1) ## Make everything a bit smaller for this inset! for label in (delta_e_ax.get_xticklabels() + delta_e_ax.get_yticklabels()): label.set_fontsize(tinyfont['size']) [i.set_linewidth(0.5) for i in delta_e_ax.spines.itervalues()] delta_e_ax.xaxis.set_major_formatter(NullFormatter()) delta_e_ax.patch.set_alpha(0) delta_e_ax.yaxis.offsetText.set_fontsize(tinyfont['size']) delta_e_ax.tick_params(axis='y', direction='in', pad=1) ## Finally, adjust the spacing and padding on the GridSpecs to make the figure look right gs.update(left=0.085, right=0.85, top=0.995, bottom=0.1, wspace=0, hspace=0.02) gs_log.update(left=0.12, right=0.995, top=0.995, bottom=0.1, wspace=0.35, hspace=1.5) ## Make sure we've got the correct figure, before saving the pdf figure('dynamics %s' % specify_sequence) savefig(os.path.join(results_path, 'individual_run_%s.pdf' % int(grid_radius * 1e6)), transparent=True)
def static_plot(self, show=True, figsize=(13,9)): """ Creates the figure, lines, texts and annotations. Returns figure and axes (in a list) for further manipulation by the user if needed. """ self.fig = plt.figure(figsize=figsize) if self.index_list is None: gs1 = matplotlib.gridspec.GridSpec(13, 1, hspace=0., wspace=0.) else: index_ncols = -(-len(self.index_list)//5) gs0 = self.fig.add_gridspec(1, 3+index_ncols) gs1 = gs0[:3].subgridspec(13, 1, hspace=0., wspace=0.) gs2 = gs0[3:].subgridspec(5, index_ncols, hspace=0.5, wspace=0.2) # indices plots for i in range(len(self.index_list)): self.index_list[i]['ax'] = plt.subplot(gs2[i%5,i//5]) self.ax1 = plt.subplot(gs1[0:5]) #SFH plot self.ax2 = plt.subplot(gs1[6:11]) #main spectrum plot self.ax3 = plt.subplot(gs1[11:]) #residual plot init_input_logM, self.total_sfh, init_custom_sfh = utils.create_sfh(self.init_comp) self.sfh_line, self.z_line, self.z_text, self.input_logM_text, self.bad_sfh_text \ = plotting.add_sfh_plot(self.init_comp, self.total_sfh, init_input_logM, self.ax1, sfh_color=self.plot_colors['sfh'], z_line_color=self.plot_colors['z']) self.model = pipes.model_galaxy(utils.make_pipes_components(self.init_comp, init_custom_sfh), spec_wavs=self.wavelengths) # full spectrum in inset self.sub_ax = plt.axes([0,0,1,1]) # Manually set the position and relative size of the inset axes within ax2 ip = InsetPosition(self.ax2, self.sub_ax_arg) self.sub_ax.set_axes_locator(ip) sub_y_scale_spec,self.sub_spec_line = plotting.add_bp_spectrum(self.model.spectrum, self.sub_ax, sub=True, color=self.plot_colors['spectrum']) self.spec_zoom_poly = self.sub_ax.fill_between(self.init_spec_lim, [0]*2, [20]*2, color=self.plot_colors['zoom'], alpha=0.1) # the main spectrum plot self.spec_line, self.run_med_line, self.overflow_text, y_scale_spec \ = plotting.add_main_spec(self.model.spectrum, self.ax2, self.init_spec_lim, median_width=self.median_width, color=self.plot_colors['spectrum'], continuum_color=self.plot_colors['continuum']) # the residual plot self.res_line = plotting.add_residual(self.model.spectrum, self.ax3, self.init_spec_lim, median_width=self.median_width, color=self.spec_line.get_color()) # indices plots if self.index_list is not None: self.index_names = [ind["name"] for ind in self.index_list] # calculate and plot indices self.indices = np.zeros(len(self.index_list)) for i in range(self.indices.shape[0]): self.indices[i] = pipes.input.spectral_indices.measure_index( self.index_list[i], self.model.spectrum, self.init_comp["redshift"]) self.index_list[i] = plotting.add_index_spectrum( self.index_list[i], self.model.spectrum, self.indices[i], self.init_comp["redshift"], y_scale_spec, color_continuum=self.plot_colors['index_continuum'], color_feature=self.plot_colors['index_feature'], alpha=0.2 ) plt.tight_layout() if show: plt.show() return self.fig, [self.ax1, self.ax2, self.ax3, self.sub_ax]
for ss in opt_s_stop: a[i].axvline(ss - prestim, linestyle='--', color='darkorange') #a[i].axvline(0, linestyle='--', color='lime') #a[i].axvline(poststim - prestim, linestyle='--', color='lime') a[i].set_title(unit) a[i].set_xlabel('Time (s)') a[i].set_ylabel('Rep') a[i].set_xlim(lim[0], lim[1]) # add inset for mwf ax2 = plt.axes([a[i].colNum, a[i].colNum, a[i].rowNum, a[i].rowNum]) # Manually set the position and relative size of the inset axes within ax1 ip = InsetPosition(a[i], [0.5, 0.5, 0.5, 0.5]) ax2.set_axes_locator(ip) mwf = io.get_mean_spike_waveform(unit, animal) ax2.plot(mwf, color='red') ax2.axis('off') else: f, ax = plt.subplots(1, 1, figsize=(6, 4)) unit = su opt_data = rec['resp'].epoch_to_signal('LIGHTON') r = rec['resp'].extract_channels([unit ]).extract_epoch('REFERENCE').squeeze() opt_mask = opt_data.extract_epoch('REFERENCE').mean(axis=(1, 2)) > 0 opt_s_stop = (np.argwhere( np.diff( opt_data.extract_epoch('REFERENCE')[opt_mask, :, :][0].squeeze()))
'ytick.labelsize': 11, 'figure.figsize': [4.248, 3.6] } plt.rcParams.update(params) fig, ax = plt.subplots() # make a little extra space between the subplots #fig.subplots_adjust(hspace=0.2) # plot for A # ax.plot(t1, np1, c='k', lineStyle='-', label='$\epsilon_p=0.01$') ax.plot(t2, np2, c='k', lineStyle='--', label='$\epsilon_p=0.06$') ax.plot(t3, np3, c='k', lineStyle='-.', label='$\epsilon_p=0.12$') ax.plot(t4, np4, c='k', lineStyle=':', label='$\epsilon_p=0.18$') ax.plot(t5, np5, c='k', lineStyle=(0, (5, 5)), label='$\epsilon_p=0.24$') ip = InsetPosition(ax, [0.2, 0.2, 0.5, 0.45]) ax2 = plt.axes([0, 0, 1, 1]) ax2.set_axes_locator(ip) ax2.plot(t1[t1 >= 0.6], np1[t1 >= 0.6], c='k', lineStyle='-') ax2.plot(t2[t2 >= 0.6], np2[t2 >= 0.6], c='k', lineStyle='--') ax2.plot(t3[t3 >= 0.6], np3[t3 >= 0.6], c='k', lineStyle='-.') ax2.plot(t4[t4 >= 0.6], np4[t4 >= 0.6], c='k', lineStyle=':') ax2.plot(t5[t5 >= 0.6], np5[t5 >= 0.6], c='k', lineStyle=(0, (5, 5))) # inset plot # mark_inset(ax, ax2, loc1=1, loc2=3, fc="none", ec='r', lw='0.5') #ax2.plot #---------------------------axis control------------------------# ax.set_xlabel("$t\ (s)$") ax.set_ylabel("Particle number")