def plot_frequencyVsParameter(\ # Specify which simulations to plot research=None,\ experiment_id="All experiments",\ simulation_id="All simulations",\ parameter_knob="vmec_parameters",\ parameter_key="rho",\ # Specify data range y_quantity='omega',\ x_range=None,\ y_range=None,\ # Details of the modes kx_range=-0.0, \ ky_range=[0,100], \ k_value=9.0, \ lineardata="average",\ # Labels x_label=None,\ y_label=None,\ title=None,\ # For the GUI the figure object already exists show_error = False,\ show_figure = False,\ ax=None, \ Progress=None,\ root=None): ''' Plot the frequency/omega or growthrate/gamma versus the wave number. Parameters ---------- research: object Contains the selected experiments and simulations. experiment_id, simulation_id: str Is used to select which simulations/experiments to plot. kvalue: {"max", integer} Determines which modes to plot. units: {"normalized", "SI units"} Determines the units of the data. lineardata: {"average", "last"} Either plot the last time value of omega/gamma or the average over the last 10% of time. ''' # Update the progress bar of the GUI if Progress: Progress.move(0, "Plot omega or gamma versus parameter.") # Decide whether to scan modes along the x-axis or y-axis scan, k_fixed, k_range = get_axisOfScan(kx_range, ky_range, root) if scan == False: return # Set the labels, and change the standard labels depending on the units label = determine_labels(x_label, y_label, kx_range, ky_range, title, "normalized", k_value, parameter_key) load_plotbox2d(x_label=label['x'], y_label=label[y_quantity], title=label["title"], ax=ax) # Keep track of the labels that are already used and save the axis limits labels = [] xlims = [0, 0] ylims = [0, 0] # Get the same amount of colors as experiments experiments = get_experiment(research, experiment_id) color = plt.cm.jet(np.linspace(0, 1, len(experiments))) #@undefinedvariable # Iterate over the experiments for experiment in experiments: #================== # GET THE DATA #================== # Get the simulations, the parameters and the omega/gamma at k_value simulations = get_simulation(experiment, simulation_id) y_dataAtKvalue = [np.NaN] * len(simulations) y_error = np.empty((2, len(simulations))) y_error[:, :] = np.NaN parameters = [] # Get the requested parameter for simulation in simulations: parameters.append( float( simulation.inputParameters[parameter_knob][parameter_key])) # Sort the simulations by this parameter sorted_indexes = list(np.array(parameters).argsort(kind="heapsort")) simulations = [simulations[i] for i in sorted_indexes] parameters = [parameters[i] for i in sorted_indexes] # Iterate over the simulations for simulation in simulations: # Get the index of the simulation i = simulations.index(simulation) # Update the progress bar of the GUI if Progress: Progress.move( i / len(simulations) * 100, "Doing analysis (" + str(i) + "/" + str(len(simulations)) + ")") # Get the modes of this simulation that need to be plotted and their indices in the (kx,ky) matrixes modes = simulation.get_modesForAOneDimensionalScan( scan, k_fixed, k_range, plotted_modes="unstable") i_kxky = simulation.get_indicesOfModes(scan, k_fixed, modes) # Get the omega or gamma at the last time value if y_quantity == "omega" and lineardata == "average": y_data = simulation.omega_avg[i_kxky] if y_quantity == "omega" and lineardata == "last": y_data = simulation.omega_last[i_kxky] if y_quantity == "gamma" and lineardata == "average": y_data = simulation.gamma_avg[i_kxky] if y_quantity == "gamma" and lineardata == "last": y_data = simulation.gamma_last[i_kxky] if y_quantity == "gamma/ky**2" and lineardata == "average": y_data = simulation.gamma_avg[i_kxky] / [m**2 for m in modes] if y_quantity == "gamma/ky**2" and lineardata == "last": y_data = simulation.gamma_last[i_kxky] / [m**2 for m in modes] # Get the error bars if y_quantity == "omega": y_error_min = simulation.omega_min[i_kxky] if y_quantity == "omega": y_error_max = simulation.omega_max[i_kxky] if y_quantity == "gamma": y_error_min = simulation.gamma_min[i_kxky] if y_quantity == "gamma": y_error_max = simulation.gamma_max[i_kxky] if y_quantity == "gamma/ky**2": y_error_min = simulation.gamma_min[i_kxky] / [ m**2 for m in modes ] if y_quantity == "gamma/ky**2": y_error_max = simulation.gamma_max[i_kxky] / [ m**2 for m in modes ] # Get the maximum of omega/gamma or omega/gamma at a specific ky if k_value == "max": try: gamma_data = simulation.gamma_avg[i_kxky] index = np.nanargmax(gamma_data) y_dataAtKvalue[i] = y_data[index] y_error[0, i] = y_error_min[index] y_error[1, i] = y_error_max[index] except: pass if k_value != "max": mask = np.isin(modes, k_value) if k_value in modes: y_dataAtKvalue[i] = y_data[mask] y_error[0, i] = y_error_min[mask] y_error[1, i] = y_error_max[mask] else: pass #================== # PLOT THE DATA #================== # Update the progress bar of the GUI if Progress: Progress.move( i / len(simulations) * 100, "Plotting analysis (" + str(i) + "/" + str(len(simulations)) + ")") # Plot the data points with the same color for each varied_value if len(modes) > 0: # Add a label to the legend for the first simulation of this experiment label_var = experiment.line_label label_var = label_var.replace( "_", " ") if "$" not in label_var else label_var label_var = "" if (label_var in labels) or ( len(experiments) <= 1) else label_var labels.append(label_var) marker_color = color[experiments.index(experiment)] # Plot the actual linear data points obtained by stella as markers (mfc = markerfacecolor; mec = markeredgecolor] print() print("Parameter", experiment.id) print(parameters) print(y_dataAtKvalue) ax.plot(parameters, y_dataAtKvalue, lw=2 ,linestyle='-', color=marker_color, ms=5 ,\ marker="o", mec="black", mfc="white", label=label_var) # Add the error bars if show_error == True: ax.errorbar(parameters, y_dataAtKvalue, yerr=y_error, fmt='o', color=marker_color, capsize=2) # Keep track of the axis limits xlims = [ np.nanmin([np.nanmin(parameters), xlims[0]]), np.nanmax([np.nanmax(parameters), xlims[1]]) ] ylims = [ np.nanmin([np.nanmin(y_dataAtKvalue), ylims[0]]), np.nanmax([np.nanmax(y_dataAtKvalue), ylims[1]]) ] # Change appearance plot ax.autoscale() ax.set_title(title) ax.ticklabel_format(style='sci', scilimits=(0, 0), axis='y') ax.legend(loc='best', labelspacing=0.0, prop={'size': 20}, framealpha=0.9) # Rescale the axis if x_range == None: x_range = xlims if y_range == None: y_range = ylims ax.set_xlim(x_range) ax.set_ylim(y_range) # Show the figure if show_figure: plt.show() return
def plot_saturatedfluxVsRho(\ # Specify which simulations to plot research=None,\ experiment_id="All experiments",\ simulation_id="All simulations",\ parameter_knob="vmec_parameters",\ parameter_key="rho",\ # Specify data range species=[0],\ y_quantity='q_flux',\ x_range=None,\ y_range=None,\ t_range=None,\ # Labels x_label=None,\ y_label=None,\ title=None,\ # For the GUI the figure object already exists show_figure = True,\ ax=None,\ Progress=None,\ # Toggles log=False,\ units="normalized"): ''' Plot saturated_flux(rho) for each shot, which is mean(heat_flux) from t=t_start to t=t_last. Parameters ---------- t_range : dict[experiment.id][simulation.id][specie] = tuple of floats Returns ------- sat_flux : dict[experiment.id][simulation.id][specie] = float ''' # Update the progress bar of the GUI if Progress: Progress.move(0,"Plot saturated flux versus parameter.") # Set the labels, and change the standard labels depending on the units label = determine_labels(x_label, y_label, title, units, species, parameter_key) load_plotbox2d(x_label=label['x'], y_label=label[y_quantity], title=label["title"], ax=ax) # Keep track of the labels that are already used and save the axis limits labels = []; xlims=[0,0]; ylims=[0,0]; #====================== # GET THE TIME RANGES #====================== # Make sure t_range contains a time range for each simulation and experiment if t_range is None: t_range = initiate_nesteddict() # Iterate over the experiments experiments = get_experiment(research, experiment_id) for experiment in experiments: # Iterate over the simulations simulations = get_simulation(experiment, simulation_id) for simulation in simulations: # Iterate over the species for s in range(simulation.dim_species): # Check whether a time range already exists timeRangeExists = False if experiment.id in t_range.keys(): if simulation.id in t_range[experiment.id].keys(): if s in t_range[experiment.id][simulation.id].keys(): timeRangeExists = True # If no t_range is assigned, choose the last 10% of the time vector if not timeRangeExists: t_start = simulation.vec_time[int(len(simulation.vec_time)*9/10)] t_range[experiment.id][simulation.id][s] = [t_start, np.NaN] # For now always make t_end = t_last t_range[experiment.id][simulation.id][s][1] = np.NaN # Delete the experiments and simulations that are no longer present experiment_ids = [ e.id for e in research.experiments] experiment_iids = list(t_range.keys()) for experiment_iid in experiment_iids: if experiment_iid not in experiment_ids: del t_range[experiment_iid] if experiment_iid in experiment_ids: simulation_ids = [ s.id for s in research.experiments[experiment_ids.index(experiment_iid)].simulations] simulation_iids = list(t_range[experiment_iid].keys()) for simulation_iid in simulation_iids: if simulation_iid not in simulation_ids: try: del t_range[simulation_iid] except: pass #================== # GET THE DATA #================== # Initiate the saturated flux which is plotted in function of a parameter sat_flux = initiate_nesteddict() parameters = initiate_nesteddict() simulation_ids = initiate_nesteddict() # Iterate over the experiments experiments = get_experiment(research, experiment_id) for experiment in experiments: parameters[experiment.id] = [] simulation_ids[experiment.id] = [] # Iterate over the simulations simulations = get_simulation(experiment, simulation_id) for simulation in simulations: # Get the requested parameter parameters[experiment.id].append(float(simulation.inputParameters[parameter_knob][parameter_key])) simulation_ids[experiment.id].append(simulation.id) # Iterate over the species for s in range(simulation.dim_species): # Get the data vec_time = simulation.vec_time vec_flux = getattr(simulation, y_quantity)[:, s] # Get the time frame t_start = t_range[experiment.id][simulation.id][s][0] t_stop = np.nanmin([vec_time[-1], t_range[experiment.id][simulation.id][s][1]]) t_range[experiment.id][simulation.id][s][1] = t_stop # Calculate the saturated flux within this time frame if t_stop <= t_start: sat_flux[experiment.id][simulation.id][s] = np.nan if t_stop > t_start: sat_flux[experiment.id][simulation.id][s] = vec_flux[(vec_time>t_start) & (vec_time<t_stop)].mean() #================== # PLOT THE DATA #================== # Iterate over the experiments experiments = get_experiment(research, experiment_id) for experiment in experiments: # Update the progress bar of the GUI i = experiments.index(experiment); length=len(experiments) if Progress: Progress.move(i/length*100,"Plotting saturated fluxes ("+str(i)+"/"+str(length)+")") # Iterate over the species for specie in species: # Add a label to the legend for the first simulation of this experiment label_var = experiment.line_label label_var = label_var.replace("_"," ") if "$" not in label_var else label_var label_var = "Electrons: "+label_var if specie==0 and len(species)>1 else label_var label_var = "Ions: "+label_var if specie==1 and len(species)>1 else label_var label_var = "Impurity: "+label_var if specie==2 and len(species)>1 else label_var label_var = "" if (label_var in labels) else label_var; labels.append(label_var) marker_color = experiment.line_color # Get the saturated flux, sorted by the parameter sorted_indexes = list(np.array(parameters[experiment.id]).argsort(kind="heapsort")) parameters[experiment.id] = [parameters[experiment.id][i] for i in sorted_indexes] saturated_flux = [sat_flux[experiment.id][simulation_ids[experiment.id][i]][specie] for i in sorted_indexes] # Plot the saturated flux versus the parameter ax.plot(parameters[experiment.id], saturated_flux, lw=2 ,linestyle='-',\ color=marker_color, ms=5, marker="o", mec="black", mfc="white", label=label_var) # Keep track of the axis limits xlims = [np.nanmin([np.nanmin(parameters[experiment.id]), xlims[0]]), np.nanmax([1.1*np.nanmax(parameters[experiment.id]), xlims[1]])] ylims = [np.nanmin([np.nanmin(saturated_flux), ylims[0]]), np.nanmax([1.1*np.nanmax(saturated_flux), ylims[1]])] # Change appearance plot ax.autoscale() ax.set_title(title) ax.ticklabel_format(style='sci', scilimits=(0,0), axis='y') ax.legend(loc='best',labelspacing=0.0, prop={'size': 20}, framealpha=0.9) # Rescale the axis if x_range==None: x_range = xlims if y_range==None: y_range = ylims ax.set_xlim(x_range) ax.set_ylim(y_range) # Show the figure if show_figure: plt.show() return sat_flux, t_range
def plot_frequencyVsTime(\ # Specify which simulations to plot research=None,\ experiment_id="All experiments",\ simulation_id="All simulations",\ # Specify data range x_range=None,\ y_range=None,\ quantity="omega",\ units="normalized",\ kx_range=-0.0,\ ky_range=[0,100],\ plotted_modes="unstable",\ # Labels x_label=None,\ y_label=None,\ title=None,\ # For the GUI the figure object already exists ax=None,\ Progress=None,\ root=None,\ # Appearance options font_size=20,\ handle_length=1): ''' Return data and plot *.omega file: time ky kx Re[om] Im[om] Re[omavg] Im[omavg] Parameters ---------- research: object Contains the selected experiments and simulations. experiment_id, simulation_id: str Is used to select which simulations/experiments to plot. plotted_modes: {"unstable", "stable", "unconverged", "converged"} Determines which modes to plot. units: {"normalized", "SI units"} Determines the units of the data. ''' # Update the progress bar of the GUI if Progress: Progress.move(0, "Plot omega or gamma versus time.") # Decide whether to scan modes along the x-axis or y-axis scan, k_fixed, k_range = get_axisOfScan(kx_range, ky_range, root) if scan == False: return # Set the labels, and change the standard labels depending on the units label = determine_labels(x_label, y_label, title, units) load_plotbox2d(x_label=label['time'], y_label=label[quantity], title=label["title"], ax=ax) # Get a reference to the experiment and its simulations experiment = get_experiment(research, experiment_id)[0] simulations = get_simulation(experiment, simulation_id) # The number of lines defines the colors so the colors of the lines change gradually with k color = get_lineColors(simulations, scan, k_fixed, k_range, plotted_modes) plot_i = 0 # Save the axis limits xlims = [0, 0] ylims = [0, 0] # Iterate over the simulations for simulation in simulations: # Get the modes of this simulation that need to be plotted vec_k = simulation.get_modesForAOneDimensionalScan( scan, k_fixed, k_range, plotted_modes) # Iterate over the modes for k in vec_k: # Update the progress bar of the GUI if Progress: Progress.move( vec_k.index(k) / len(vec_k) * 100, "Plotting modes (" + str(vec_k.index(k)) + "/" + str(len(vec_k)) + ")") # Get the indices of the mode i_kx, i_ky = simulation.get_indicesOfMode(scan, k_fixed, k) # Labels for the legend simulation_id = simulation.marker_label.replace('_', ' ') if isinstance(kx_range, float): label = "$k_y\\rho_i = " + "{0:.2f}".format(k) + "$" if isinstance(ky_range, float): label = "$k_x\\rho_i = " + "{0:.2f}".format(k) + "$" if len(simulations) > 1: label = label + ": " + simulation_id if len(vec_k) == 1: label = simulation_id # Get the time axis of the mode time = simulation.time_kxky[:, i_kx, i_ky] ydata = simulation.omega_kxky[:, i_kx, i_ky] if quantity == "omega" else simulation.gamma_kxky[:, i_kx, i_ky] # Only plot as long as omega and gamma are not NaN time = time[np.isfinite(ydata)] ydata = ydata[np.isfinite(ydata)] # Denormalize the data if necessary if units == "SI units": ref = { "length": simulation.referenceUnits["length"], "vthermal": simulation.referenceUnits["vthermal"] } if units != "SI units": ref = {"length": 1, "vthermal": 1} time = time * ref["length"] / ref["vthermal"] ydata = ydata / ref["length"] * ref["vthermal"] # Plot omega(t) and gamma(t) ax.plot(time, ydata, lw=2, linestyle='-', color=color[plot_i], label=label) plot_i += 1 # Keep track of the axis limits xlims = [min(time.min(), xlims[0]), max(time.max(), xlims[1])] ylims = [ min(abs(ydata).min(), ylims[0]), max(1.5 * abs(ydata[-1]).max(), ylims[1]) ] # If there were modes to be plotted, rescale and show the figure. if xlims != [0, 0] and ylims != [0, 0]: # Rescale the axis if x_range == None: x_range = xlims if y_range == None: y_range = ylims rescale_axes(ax, x_range, y_range, units, font_size, handle_length, simulation_id) # Show the figure if we're not in a GUI if not root: plt.show() # If there were no modes, just clear the axis else: ax.clear() print("WARNING: There were no modes to be plotted.") # End if True: return
def plot_fluxesVsTime(\ # Specify which simulations to plot research=None,\ experiment_id="All experiments",\ simulation_id="All simulations",\ sat_flux=None,\ # Specify data range species=[0],\ y_quantity='q_flux',\ x_range=None,\ y_range=None,\ t_range=None,\ # Labels x_label=None,\ y_label=None,\ title=None,\ # For the GUI the figure object already exists show_figure = True,\ ax=None,\ Progress=None,\ # Toggles show_restartTimes=False,\ show_vspan=True,\ normalize=False,\ log=False,\ units="normalized"): ''' Plot heat_flux(t) for each shot Parameters ---------- t_range : dict[experiment.id][simulation.id][specie] = tuple of floats sat_flux : dict[experiment.id][simulation.id][specie] = float ''' # Update the progress bar of the GUI if Progress: Progress.move(0, "Plot flux versus time.") # Set the labels, and change the standard labels depending on the units label = determine_labels(x_label, y_label, title, units, species, normalize) load_plotbox2d(x_label=label['x'], y_label=label[y_quantity], title=label["title"], ax=ax) # Keep track of the labels that are already used and save the axis limits labels = [] xlims = [0, 0] ylims = [0, 0] # Plot the electron and ion labels if len(species) > 1: ax.plot(-1, -1, lw=3, linestyle='-', color='black', label='Ions') ax.plot(-1, -1, lw=3, linestyle=':', color='black', label='Electrons') # Get the total number of varied values, to determine whether we need to use markers # to diferentiate between different simulations or whether the line colors are sufficient number_ofVariedValues = 0 experiments = get_experiment(research, experiment_id) for experiment in experiments: number_ofVariedValues = np.max( [number_ofVariedValues, len(experiment.variedValues)]) # Iterate over the experiments for experiment in experiments: # First plot the lines with the same color for each experiment if (len(experiments) > 1) or (number_ofVariedValues == 1): # Iterate over the simulations simulations = get_simulation(experiment, simulation_id) for simulation in simulations: # Iterate over the species for specie in species: # Get the data vec_time = simulation.vec_time vec_flux = getattr(simulation, y_quantity)[:, specie] style = ':' if (specie == '1' and len(species) > 1) else '-' # Normalize the data if sat_flux and normalize: vec_flux = vec_flux / sat_flux[experiment.id][ simulation.id][specie] try: vec_time = vec_time / t_range[experiment.id][ simulation.id]["time peak"] except: t_range[experiment.id][simulation.id][ "time peak"] = calculate_peakTime( vec_time, vec_flux) vec_time = vec_time / t_range[experiment.id][ simulation.id]["time peak"] # Put time time axis in milliseconds if we plot in SI units if units != "normalized": vec_time = vec_time * 1000 # Add a label to the legend for the first simulation of this experiment label_exp = experiment.line_label if simulations.index( simulation) == 0 else "" # Plot the data ax.plot(vec_time, vec_flux, lw=3, linestyle=style, color=experiment.line_color, label=label_exp) # Plot the data points with the same color for each varied_value for experiment in experiments: # Iterate over the simulations simulations = get_simulation(experiment, simulation_id) for simulation in simulations: # Iterate over the species for specie in species: # Get the data vec_time = simulation.vec_time vec_flux = getattr(simulation, y_quantity)[:, specie] style = ':' if (specie == '1' and len(species) > 1) else '-' # Normalize the data if sat_flux and normalize: vec_flux = vec_flux / sat_flux[experiment.id][ simulation.id][specie] try: vec_time = vec_time / t_range[experiment.id][ simulation.id]["time peak"] except: t_range[experiment.id][ simulation.id]["time peak"] = calculate_peakTime( vec_time, vec_flux) vec_time = vec_time / t_range[experiment.id][ simulation.id]["time peak"] # Put time time axis in milliseconds if we plot in SI units if units != "normalized": vec_time = vec_time * 1000 # Add a label to the legend for the first simulation of this experiment label_var = simulation.marker_label label_var = label_var.replace( "_", " ") if "$" not in label_var else label_var label_var = "" if (label_var in labels) else label_var labels.append(label_var) label_var1 = label_var if not ( (len(experiments) > 1) or (number_ofVariedValues == 1)) else "" label_var2 = label_var if (len(experiments) > 1) or ( number_ofVariedValues == 1) else "" marker_style = simulation.marker_style marker_color = simulation.marker_color # If there is only one experiment, add lines in the same color as the marker if not ((len(experiments) > 1) or (number_ofVariedValues == 1)): lw = 2 if (len(experiments) > 1) or (number_ofVariedValues == 1): lw = 0 # First print the lines with the shot label: for ions and electrons ax.plot(vec_time, vec_flux, lw=lw, linestyle=style, color=marker_color, label=label_var1) # Keep track of the axis limits xlims = [ np.nanmin([np.nanmin(vec_time), xlims[0]]), np.nanmax([1.1 * np.nanmax(vec_time), xlims[1]]) ] ylims = [ np.nanmin([np.nanmin(vec_flux), ylims[0]]), np.nanmax([1.1 * np.nanmax(vec_flux), ylims[1]]) ] # Next print the symbols/markers with the rho label, print the markers differently for log and normal scales if (len(experiments) > 1) or (number_ofVariedValues == 1): vec_flux, vec_time = get_markerAtEveryXSteps( vec_flux, vec_time, log, units) ax.plot(vec_time, vec_flux, lw=0, marker=marker_style, mec=marker_color, mfc=marker_color, label=label_var2) # Show the area where the saturated flux is calculated if show_restartTimes: for experiment in experiments: simulations = get_simulation(experiment, simulation_id) for simulation in simulations: for time in simulation.restart_times: print("RESTART TIME", experiment.id, simulation.id, time) ax.axvline(x=time, color=experiment.line_color) # Show the area where the saturated flux is calculated if sat_flux and show_vspan: for experiment in experiments: simulations = get_simulation(experiment, simulation_id) for simulation in simulations: for specie in species: t_start = t_range[experiment.id][simulation.id][specie][0] t_stop = t_range[experiment.id][simulation.id][specie][1] if normalize: t_start = t_start / t_range[experiment.id][ simulation.id]["time peak"] t_stop = t_stop / t_range[experiment.id][ simulation.id]["time peak"] ax.axvspan(t_start, t_stop, alpha=0.5, color=simulation.marker_color) # Add a line to indicate the saturated flux mean if sat_flux: for experiment in experiments: simulations = get_simulation(experiment, simulation_id) for simulation in simulations: for specie in species: # The label can show the exact value label = "" #'$Q_{sat}/Q_{gB} =$'+"{:.2f}".format(sat_flux[simulation][specie]) # The color either matches the experiment, the varied value or the species if (len(experiments) > 1) or (number_ofVariedValues == 1): color = experiment.line_color else: color = simulation.line_color style = ':' if (specie == '1' and len(species) > 1) else '-' # Only plot the saturated flux over the time range where it is averaged over t_start = t_range[experiment.id][simulation.id][specie][0] t_stop = t_range[experiment.id][simulation.id][specie][1] vec_time = np.linspace(t_start, t_stop, 10) # Manually construct the saturated flux vector saturated_flux = np.ones(len(vec_time)) * sat_flux[ experiment.id][simulation.id][specie] # Plot the saturated flux ax.plot(vec_time, saturated_flux, lw=2, linestyle=style, color=color, label=label) # Change appearance plot ax.autoscale() ax.set_title(title) ax.set_xlim(xmin=0) ax.ticklabel_format(style='sci', scilimits=(0, 0), axis='y') ax.legend(labelspacing=0.0, prop={'size': 20}, handlelength=1.5) if log == True: ax.set_yscale('log') # Rescale the axis if x_range == None: x_range = xlims if y_range == None: y_range = ylims ax.set_xlim(x_range) ax.set_ylim(y_range) # Show the figure if show_figure: plt.show() if True: return
def plot_profilesVsRho(\ # Get the data raw_files, \ # Define the radial coordinate x1='rho', \ a1=None, \ x2='rho', \ a2=None, \ # State in which columns the data can be found x_col1=None, \ dens_col1=None, \ Ti_col1=None, \ Te_col1=None, \ x_col2=None, \ dens_col2=None, \ Ti_col2=None, \ Te_col2=None, \ # If it is called from the GUI, the figure exists save = False, \ ax1 = None, ax1_twin = None, \ ax2 = None, ax2_twin = None, \ ax3 = None, ax3_twin = None, \ plot = "profiles"): ''' Obtain the gradients and values of the n_e, T_e and T_i profiles at specific rho values Parameters ---------- folder, source_file : str specify the folder in the runs directory and the source_file with extension x : {'rho', 's', 'r'} Specify the units of the x-axis, this will be converted into rho If [x] = 'r' also specify the minor radius [a] x_col, dens_col, Ti_col, Te_col : int Specify in which columns the quantities can be found plot : {"a/Ln", "profiles", "gradients", "normalized gradients", "relative comparison"} If the figure already exists, select what to plot on it BASH: plot_profiles --x=0 --n=2 --Te=3 --Ti=4 ''' # Plot everything if the figure doesn't exist if ax1 == None: plot = "all" plt.rc('font', size=25) # Set-up the figure for the profiles if plot in ["profiles", "gradients", "normalized gradients"]: # Profiles of density; electron temperature; ion temperature if plot in ["profiles"]: ax_profileDensity = ax1 ax_profileEleTemp = ax2 ax_profileIonTemp = ax3 # Real gradients of density; electron temperature; ion temperature if plot in ["gradients"]: ax_gradientsDensity = ax1 ax_gradientsEleTemp = ax2 ax_gradientsIonTemp = ax3 # Normalized logaritmic gradients of density; electron temperature; ion temperature if plot in ["normalized gradients"]: ax_normGradDensity = ax1 ax_normGradEleTemp = ax2 ax_normGradIonTemp = ax3 if plot == "all": fig = plt.figure(figsize=(13, 10)) gs = gridspec.GridSpec(3, 3) gs.update(wspace=0.35, hspace=0.15, top=0.97, bottom=0.1) ax_profileDensity = plt.subplot(gs[0]) ax_profileEleTemp = plt.subplot(gs[1]) ax_profileIonTemp = plt.subplot(gs[2]) ax_gradientsDensity = plt.subplot(gs[3]) ax_gradientsEleTemp = plt.subplot(gs[4]) ax_gradientsIonTemp = plt.subplot(gs[5]) ax_normGradDensity = plt.subplot(gs[6]) ax_normGradEleTemp = plt.subplot(gs[7]) ax_normGradIonTemp = plt.subplot(gs[8]) # Make the plots pretty if plot == "all" or plot in ["profiles"]: xlab = "" if plot == "all" else '$\\rho = r/a$' load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label='${n_e}$ $[10^{19}$m$^{-3}]$', title="", ax=ax_profileDensity, title_size='small') load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label='${T_i}$ [keV]', title="", ax=ax_profileEleTemp, title_size='small') load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label='${T_e}$ [keV]', title="", ax=ax_profileIonTemp, title_size='small') if plot == "all" or plot in ["gradients"]: xlab = "" if plot == "all" else '$\\rho = r/a$' load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label="$-n'_e$ $[10^{19}$m$^{-4}]$", ax=ax_gradientsDensity) load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label="$-T'_i$ [keV/m]", ax=ax_gradientsEleTemp) load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label="$-T'_e$ [keV/m]", ax=ax_gradientsIonTemp) if plot == "all" or plot in ["normalized gradients"]: xlab = '$\\rho = r/a$' load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label='$a/L_{n_e}$', ax=ax_normGradDensity) load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label='$a/L_{T_i}$', ax=ax_normGradEleTemp) load_plotbox2d(x_range=[0, 1], x_label=xlab, y_label='$a/L_{T_e}$', ax=ax_normGradIonTemp) # All normalized gradients if plot in ["a/Ln"]: load_styleFigures() ax_allNormGradProf1 = ax1 ax_allNormGradProf2 = ax2 load_plotbox2d(x_label='$\\rho = r/a$', y_label='$a/L$', fig_size=(8.5, 7.5), ax=ax_allNormGradProf1) load_plotbox2d(x_label='$\\rho = r/a$', y_label='$a/L$', fig_size=(8.5, 7.5), ax=ax_allNormGradProf2) ax_allNormGradProf1Twin = ax1_twin # Create a second axis for Te/Ti ax_allNormGradProf2Twin = ax2_twin # Create a second axis for Te/Ti ax_allNormGradProf1Twin.set_ylabel("$T_e/T_i$", color='navy') ax_allNormGradProf1Twin.tick_params(axis='y', labelcolor='navy', colors='navy') ax_allNormGradProf2Twin.set_ylabel("$T_e/T_i$", color='navy') ax_allNormGradProf2Twin.tick_params(axis='y', labelcolor='navy', colors='navy') ax_allNormGradProf = ax3 load_plotbox2d(x_label='$\\rho = r/a$', y_label='$a/L$', fig_size=(12, 6), ax=ax_allNormGradProf) ax_allNormGradProfTwin = ax3_twin ax_allNormGradProfTwin.set_ylabel("$T_e/T_i$", color='navy') ax_allNormGradProfTwin.tick_params(axis='y', labelcolor='navy') # Compare two profiles if plot in ["relative comparison"]: ax_allNormGradProf = ax1 load_plotbox2d(x_label='$\\rho = r/a$', y_label='$a/L$', fig_size=(12, 6), ax=ax_allNormGradProf) ax_allNormGradProfTwin = ax1_twin ax_allNormGradProfTwin.set_ylabel("$T_e/T_i$", color='navy') ax_allNormGradProfTwin.tick_params(axis='y', labelcolor='navy') ax_relativeNormGrad = ax2 load_plotbox2d(x_label='$\\rho = r/a$', y_label='$( a/L_{2} - a/L_{1} ) / (a/L_{1})$', ax=ax_relativeNormGrad) ax_relativeNormGradTwin = ax2_twin ax_relativeNormGradTwin.set_ylabel( "$( (T_e/T_i)_{2} - (T_e/T_i)_{1} ) / (T_e/T_i)_{1}$", color='navy') ax_relativeNormGradTwin.tick_params(axis='y', labelcolor='navy') if plot in ["all"]: fig3 = plt.figure(figsize=(7, 6)) gs2 = gridspec.GridSpec(1, 2) ax_allNormGradProf1 = plt.subplot(gs2[0]) ax_allNormGradProf2 = plt.subplot(gs2[1]) load_plotbox2d(x_label='$\\rho = r/a$', y_label='$a/L$', fig_size=(8.5, 7.5), ax=ax_allNormGradProf1) load_plotbox2d(x_label='$\\rho = r/a$', y_label='$a/L$', fig_size=(8.5, 7.5), ax=ax_allNormGradProf2) ax_allNormGradProf1Twin = ax_allNormGradProf1.twinx( ) # Create a second axis for Te/Ti ax_allNormGradProf2Twin = ax_allNormGradProf2.twinx( ) # Create a second axis for Te/Ti ax_allNormGradProf1Twin.set_ylabel("$T_e/T_i$", color='navy') ax_allNormGradProf1Twin.tick_params(axis='y', labelcolor='navy') ax_allNormGradProf2Twin.set_ylabel("$T_e/T_i$", color='navy') ax_allNormGradProf2Twin.tick_params(axis='y', labelcolor='navy') fig2 = plt.figure(figsize=(14, 6)) gs3 = gridspec.GridSpec(1, 1) ax_allNormGradProf = plt.subplot(gs3[0]) load_plotbox2d(x_label='$\\rho = r/a$', y_label='$a/L$', fig_size=(12, 6), ax=ax_allNormGradProf) ax_allNormGradProfTwin = ax_allNormGradProf.twinx() ax_allNormGradProfTwin.set_ylabel("$T_e/T_i$", color='navy') ax_allNormGradProfTwin.tick_params(axis='y', labelcolor='navy') fig4 = plt.figure(figsize=(7.5, 6)) gs4 = gridspec.GridSpec(1, 1) ax_relativeNormGrad = plt.subplot(gs4[0]) load_plotbox2d(x_label='$\\rho = r/a$', y_label='$( a/L_{2} - a/L_{1} ) / (a/L_{1})$', ax=ax_relativeNormGrad) ax_relativeNormGradTwin = ax_relativeNormGrad.twinx() ax_relativeNormGradTwin.set_ylabel( "$( (T_e/T_i)_{2} - (T_e/T_i)_{1} ) / (T_e/T_i)_{1}$", color='navy') ax_relativeNormGradTwin.tick_params(axis='y', labelcolor='navy') # Count the data files count = 0 # Read the data file containig the profiles for raw_file in raw_files: # Count the data files count += 1 # Read the data try: data = np.loadtxt(raw_file, dtype='float') except: data = np.loadtxt(raw_file, dtype=np.str, delimiter='\t', skiprows=1) data = np.char.replace(data, ',', '.').astype(np.float64) # If the columns are not specified, try to guess if count == 1: x = x1 a = a1 if (x_col1 is None) or (dens_col1 is None) or ( Ti_col1 is None) or (Te_col1 is None): x_col, dens_col, Ti_col, Te_col = guess_columns(raw_file) else: x_col, dens_col, Ti_col, Te_col = x_col1, dens_col1, Ti_col1, Te_col1 if count == 2: x = x2 a = a2 if (x_col2 is None) or (dens_col2 is None) or ( Ti_col2 is None) or (Te_col2 is None): x_col, dens_col, Ti_col, Te_col = guess_columns(raw_file) else: x_col, dens_col, Ti_col, Te_col = x_col2, dens_col2, Ti_col2, Te_col2 # The "Ne_fits" file contains the data of two experiments! if "Ne_fits" in str(raw_file): if count == 1: x_col = 0 dens_col = 1 Ti_col = 3 Te_col = 2 if count == 2: x_col = 0 dens_col = 4 Ti_col = 6 Te_col = 5 # Change the unit along the x-axis to rho=r/a=sqrt(s) if x == 'r': data[:, x_col] = data[:, x_col] / a if x == 's': data[:, x_col] = np.sqrt(data[:, x_col]) # Add shot labels if count == 1: label_S = "Profile 1" color = "navy" style = '-' if count == 2: label_S = "Profile 2" color = "crimson" style = '--' # Density: Get the profiles and gradients and plot them Y_prof, Y_grad, a_over_Ly, x_vec = calculate_gradients(data, rho_col=x_col, Y_col=dens_col) if plot == "all" or plot in ["profiles"]: ax_profileDensity.plot(x_vec, Y_prof, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if plot == "all" or plot in ["gradients"]: ax_gradientsDensity.plot(x_vec, -Y_grad, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if plot == "all" or plot in ["normalized gradients"]: ax_normGradDensity.plot(x_vec, a_over_Ly, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if count == 1: a_over_Ln_ld = a_over_Ly n_prof_ld = Y_prof if count == 2: a_over_Ln_hd = a_over_Ly n_prof_hd = Y_prof # Ti: Get the profiles and gradients and plot them Y_prof, Y_grad, a_over_Ly, x_vec = calculate_gradients(data, rho_col=x_col, Y_col=Ti_col) if plot == "all" or plot in ["profiles"]: ax_profileEleTemp.plot(x_vec, Y_prof, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if plot == "all" or plot in ["gradients"]: ax_gradientsEleTemp.plot(x_vec, -Y_grad, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if plot == "all" or plot in ["normalized gradients"]: ax_normGradEleTemp.plot(x_vec, a_over_Ly, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if count == 1: a_over_LTi_ld = a_over_Ly Ti_prof_ld = Y_prof if count == 2: a_over_LTi_hd = a_over_Ly Ti_prof_hd = Y_prof # Te: Get the profiles and gradients and plot them Y_prof, Y_grad, a_over_Ly, x_vec = calculate_gradients(data, rho_col=x_col, Y_col=Te_col) if plot == "all" or plot in ["profiles"]: ax_profileIonTemp.plot(x_vec, Y_prof, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if plot == "all" or plot in ["gradients"]: ax_gradientsIonTemp.plot(x_vec, -Y_grad, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if plot == "all" or plot in ["normalized gradients"]: ax_normGradIonTemp.plot(x_vec, a_over_Ly, style, color=color, linewidth=4, markerfacecolor='white', label=label_S) if count == 1: a_over_LTe_ld = a_over_Ly Te_prof_ld = Y_prof if count == 2: a_over_LTe_hd = a_over_Ly Te_prof_hd = Y_prof # Plot all gradients together in two subplots, one shot per subplot if plot == "all" or plot in ["a/Ln"]: ax_allNormGradProf1.plot(x_vec, a_over_Ln_ld, color='black', linewidth=3, markerfacecolor='white', label="$a/L_n$") ax_allNormGradProf1.plot(x_vec, a_over_LTi_ld, color='green', linewidth=3, markerfacecolor='white', label="$a/L_{T_i}$") ax_allNormGradProf1.plot(x_vec, a_over_LTe_ld, color='red', linewidth=3, markerfacecolor='white', label="$a/L_{T_e}$") ax_allNormGradProf1Twin.plot(x_vec, Te_prof_ld / Ti_prof_ld, color='navy', linewidth=3, markerfacecolor='white', label='') ax_allNormGradProf1.plot(-1, -1, color='navy', linewidth=3, label='$T_e/T_i$') if len(raw_files) != 1: ax_allNormGradProf2.plot(x_vec, a_over_Ln_hd, color='black', linewidth=3, markerfacecolor='white', label="$a/L_n$") ax_allNormGradProf2.plot(x_vec, a_over_LTi_hd, color='green', linewidth=3, markerfacecolor='white', label="$a/L_{T_i}$") ax_allNormGradProf2.plot(x_vec, a_over_LTe_hd, color='red', linewidth=3, markerfacecolor='white', label="$a/L_{T_e}$") ax_allNormGradProf2Twin.plot(x_vec, Te_prof_hd / Ti_prof_hd, color='navy', linewidth=3, markerfacecolor='white', label='') ax_allNormGradProf2.plot(-1, -1, color='navy', linewidth=3, label='$T_e/T_i$') # Plot al gradients together in one subplot if plot == "all" or plot in ["relative comparison", "a/Ln"]: ax_allNormGradProf.plot(x_vec, a_over_Ln_ld, color='black', ls='-', linewidth=3, markerfacecolor='white', label="$a/L_n$") ax_allNormGradProf.plot(x_vec, a_over_LTi_ld, color='green', ls='-', linewidth=3, markerfacecolor='white', label="$a/L_{T_i}$") ax_allNormGradProf.plot(x_vec, a_over_LTe_ld, color='red', ls='-', linewidth=3, markerfacecolor='white', label="$a/L_{T_e}$") ax_allNormGradProfTwin.plot(x_vec, Te_prof_ld / Ti_prof_ld, color='navy', ls='-', linewidth=3, markerfacecolor='white', label='') ax_allNormGradProf.plot(-1, -1, color='navy', linewidth=3, label='$T_e/T_i$') if len(raw_files) != 1: ax_allNormGradProf.plot(x_vec, a_over_Ln_hd, color='black', ls='--', linewidth=3, markerfacecolor='white', label="") ax_allNormGradProf.plot(x_vec, a_over_LTi_hd, color='green', ls='--', linewidth=3, markerfacecolor='white', label="") ax_allNormGradProf.plot(x_vec, a_over_LTe_hd, color='red', ls='--', linewidth=3, markerfacecolor='white', label="") ax_allNormGradProfTwin.plot(x_vec, Te_prof_hd / Ti_prof_hd, color='navy', ls='--', linewidth=3, markerfacecolor='white', label='') ax_allNormGradProf.plot(-1, -1, color='navy', linewidth=3, label='') # Plot the percentual differences: Profile 2 is reference so difference = (ld-hd)/hd if plot == "all" or plot in ["relative comparison"]: if len(raw_files) != 1: ax_relativeNormGrad.plot(x_vec, (a_over_Ln_ld - a_over_Ln_hd) / a_over_Ln_hd * 100, color='black', ls='-', linewidth=3, label="$a/L_n$") ax_relativeNormGrad.plot(x_vec, (a_over_LTi_ld - a_over_LTi_hd) / a_over_LTi_hd * 100, color='green', ls='-', linewidth=3, label="$a/L_{T_i}$") ax_relativeNormGrad.plot(x_vec, (a_over_LTe_ld - a_over_LTe_hd) / a_over_LTe_hd * 100, color='red', ls='-', linewidth=3, label="$a/L_{T_e}$") ax_relativeNormGradTwin.plot( x_vec, (Te_prof_ld / Ti_prof_ld - Te_prof_hd / Ti_prof_hd) / (Te_prof_hd / Ti_prof_hd) * 100, color='navy', ls='-', linewidth=3, label='') ax_relativeNormGrad.plot(-1, -1, color='navy', linewidth=3, label='$T_e/T_i$') # Finish the figures if plot == "all" or plot in ["profiles"]: ax_profileDensity.set_title("Density profile") ax_profileEleTemp.set_title("Electron temperature profile") ax_profileIonTemp.set_title("Ion temperature profile") for ax in [ax_profileDensity, ax_profileEleTemp, ax_profileIonTemp]: ax.autoscale() ax.set_xlim(xmin=0, xmax=1) ax.set_ylim(ymin=0) ax.set_ylim(ymax=10) if plot == "all" or plot in ["gradients"]: ax_gradientsDensity.set_title("Density gradients") ax_gradientsEleTemp.set_title("Electron temperature gradients") ax_gradientsIonTemp.set_title("Ion temperature gradients") for ax in [ ax_gradientsDensity, ax_gradientsEleTemp, ax_gradientsIonTemp ]: ax.autoscale() ax.set_xlim(xmin=0, xmax=1) ax.set_ylim(ymin=0) ax.set_ylim(ymax=10) if plot == "all" or plot in ["normalized gradients"]: ax_normGradDensity.set_title("Normalized density gradients") ax_normGradEleTemp.set_title( "Normalized electron temperature gradients") ax_normGradIonTemp.set_title("Normalized ion temperature gradients") for ax in [ax_normGradDensity, ax_normGradEleTemp, ax_normGradIonTemp]: ax.autoscale() ax.set_xlim(xmin=0, xmax=1) ax.set_ylim(ymin=0) ax.set_ylim(ymax=10) if plot == "all" or plot in ["a/Ln"]: ax_allNormGradProf1.set_title("Profile 1") ax_allNormGradProf2.set_title("Profile 2") for ax in [ ax_allNormGradProf1, ax_allNormGradProf2, ax_allNormGradProf1Twin, ax_allNormGradProf2Twin ]: ax.autoscale() ax.set_xlim(xmin=0, xmax=1) ax.set_ylim(ymin=0) ax.set_ylim(ymax=10) if plot == "all" or plot in ["relative comparison", "a/Ln"]: ax_allNormGradProf.set_title("Both profiles") for ax in [ax_allNormGradProf, ax_allNormGradProfTwin]: ax.autoscale() ax.set_xlim(xmin=0, xmax=1) ax.set_ylim(ymin=0) ax.set_ylim(ymax=10) if plot == "all" or plot in ["relative comparison"]: ax_relativeNormGrad.set_title("Relative comparison") ax_relativeNormGrad.yaxis.set_major_formatter( ticker.PercentFormatter()) ax_relativeNormGradTwin.yaxis.set_major_formatter( ticker.PercentFormatter()) for ax in [ax_relativeNormGrad, ax_relativeNormGradTwin]: ax.autoscale() ax.set_xlim(xmin=0, xmax=1) ax.set_ylim(ymin=-20, ymax=20) # Legend if plot == "all" or plot in [ "profiles", "gradients", "normalized gradients" ]: if plot == "all" or plot in ["profiles"]: for ax in [ ax_profileDensity, ax_profileEleTemp, ax_profileIonTemp ]: if len(raw_files) > 1 or plot == "all": ax.legend(loc='upper right', labelspacing=0.1, prop={'size': 20}) if plot == "all" or plot in ["gradients"]: for ax in [ ax_gradientsDensity, ax_gradientsEleTemp, ax_gradientsIonTemp ]: if len(raw_files) > 1 or plot == "all": ax.legend(loc='upper left', labelspacing=0.1, prop={'size': 20}) if plot == "all" or plot in ["normalized gradients"]: for ax in [ ax_normGradDensity, ax_normGradEleTemp, ax_normGradIonTemp ]: if len(raw_files) > 1 or plot == "all": ax.legend(loc='upper left', labelspacing=0.1, prop={'size': 20}) if plot == "all": ax.yaxis.set_label_coords(-0.13, 0.5) if plot == "all" or plot in ["a/Ln"]: for ax in [ ax_allNormGradProf1, ax_allNormGradProf2, ax_allNormGradProf ]: ax.legend(loc='upper left', labelspacing=0.1, prop={'size': 20}) for ax in [ax_allNormGradProfTwin]: ax.plot([-1, -2], [-1, -2], color="black", ls='-', label="Profile 1") ax.plot([-1, -2], [-1, -2], color="black", ls='--', label="Profile 2") ax.legend(loc='upper right', labelspacing=0.1, prop={'size': 20}) if plot == "all" or plot in ["relative comparison"]: for ax in [ax_relativeNormGrad]: ax.legend(labelspacing=0.1, prop={'size': 20}) # Show the figure if plot == "all": plt.show() return
def plot_potentialVsTime(\ # Specify which simulations to plot research=None,\ experiment_id="All experiments",\ simulation_id="All simulations",\ # Specify data range x_range=None,\ y_range=None,\ # Labels x_label=None,\ y_label=None,\ title=None,\ # For the GUI the figure object already exists show_figure = True,\ ax=None,\ Progress=None,\ # Toggles log=False,\ units="normalized"): ''' Plot potential(t). ''' # Update the progress bar of the GUI if Progress: Progress.move(0, "Plot potential versus time.") # Set the labels, and change the standard labels depending on the units label = determine_labels(x_label, y_label, title, units) load_plotbox2d(x_label=label['x'], y_label=label["y"], title=label["title"], ax=ax) # Keep track of the labels that are already used and save the axis limits labels = [] xlims = [0, 0] ylims = [0, 0] # Get the total number of varied values, to determine whether we need to use markers # to diferentiate between different simulations or whether the line colors are sufficient number_ofVariedValues = 0 experiments = get_experiment(research, experiment_id) for experiment in experiments: number_ofVariedValues = np.max( [number_ofVariedValues, len(experiment.variedValues)]) # Iterate over the experiments for experiment in experiments: # First plot the lines with the same color for each experiment if (len(experiments) > 1) or (number_ofVariedValues == 1): # Iterate over the simulations simulations = get_simulation(experiment, simulation_id) for simulation in simulations: # Get the data vec_time = simulation.time vec_phi2 = simulation.phi2 style = '-' # Put time time axis in milliseconds if we plot in SI units if units != "normalized": vec_time = vec_time * 1000 # Add a label to the legend for the first simulation of this experiment label_exp = experiment.line_label if simulations.index( simulation) == 0 else "" # Plot the data ax.plot(vec_time, vec_phi2, lw=3, linestyle=style, color=experiment.line_color, label=label_exp) # Plot the data points with the same color for each varied_value for experiment in experiments: # Iterate over the simulations simulations = get_simulation(experiment, simulation_id) for simulation in simulations: # Get the data vec_time = simulation.time vec_phi2 = simulation.phi2 style = '-' # Put time time axis in milliseconds if we plot in SI units if units != "normalized": vec_time = vec_time * 1000 # Add a label to the legend for the first simulation of this experiment label_var = simulation.marker_label label_var = label_var.replace( "_", " ") if "$" not in label_var else label_var label_var = "" if (label_var in labels) else label_var labels.append(label_var) label_var1 = label_var if not ( (len(experiments) > 1) or (number_ofVariedValues == 1)) else "" label_var2 = label_var if (len(experiments) > 1) or ( number_ofVariedValues == 1) else "" marker_style = simulation.marker_style marker_color = simulation.marker_color # If there is only one experiment, add lines in the same color as the marker if not ((len(experiments) > 1) or (number_ofVariedValues == 1)): lw = 2 if (len(experiments) > 1) or (number_ofVariedValues == 1): lw = 0 # First print the lines with the shot label: for ions and electrons ax.plot(vec_time, vec_phi2, lw=lw, linestyle=style, color=marker_color, label=label_var1) # Keep track of the axis limits xlims = [ np.nanmin([np.nanmin(vec_time), xlims[0]]), np.nanmax([1.1 * np.nanmax(vec_time), xlims[1]]) ] ylims = [ np.nanmin([np.nanmin(vec_phi2), ylims[0]]), np.nanmax([1.1 * np.nanmax(vec_phi2), ylims[1]]) ] # Next print the symbols/markers with the rho label, print the markers differently for log and normal scales if (len(experiments) > 1) or (number_ofVariedValues == 1): vec_flux, vec_time = get_markerAtEveryXSteps( vec_phi2, vec_time, log, units) ax.plot(vec_time, vec_flux, lw=0, marker=marker_style, mec=marker_color, mfc=marker_color, label=label_var2) # Change appearance plot ax.autoscale() ax.set_title(title) ax.set_xlim(xmin=0) ax.ticklabel_format(style='sci', scilimits=(0, 0), axis='y') ax.legend(labelspacing=0.0, prop={'size': 20}, handlelength=1.5) if log == True: ax.set_yscale('log') # Rescale the axis if x_range == None: x_range = xlims if y_range == None: y_range = ylims ax.set_xlim(x_range) ax.set_ylim(y_range) # Show the figure if show_figure: plt.show() if True: return
def plot_potentialVsZ(\ # Specify which simulations to plot research=None,\ experiment_id="All experiments",\ simulation_id="All simulations",\ # Specify data range units="normalized",\ x_quantity="z",\ y_quantity="phi_real",\ x_range=None,\ y_range=None,\ plotted_modes="unstable",\ kx_range=-0.0,\ ky_range=[0,100],\ # Labels x_label=None,\ y_label=None,\ title=None,\ # For the GUI the figure object already exists ax=None,\ Progress=None,\ root=None,\ # Appearance options font_size=20,\ handle_length=1): ''' Plot phi(z) to see if <nfield_periods> was big enough. The z-axis can be displaced in zeta <zeta>, in z <z>, in poloidal turns <pol> and toroidal turns <tor>. Data files needed ----------------- *.in *.out.nc or *.out.h5 *.final_fields Parameters ---------- units : {normalized; SI units} y_quantity : {phi2; phi_real; phi_imag} x_quantity : {zeta; z; pol} Notes ----- Structure of the *.final_fields file # z z-thet0 aky akx real(phi) imag(phi) real(apar) imag(apar) z_eqarc-thet0 ''' # Update the progress bar of the GUI if Progress: Progress.move(0, "Plot the potential versus z.") # Decide whether to scan modes along the x-axis or y-axis scan, k_fixed, k_range = get_axisOfScan(kx_range, ky_range, root) if scan == False: return # Set the labels, and change the standard labels depending on the units label = determine_labels(x_label, y_label, title, units) load_plotbox2d(x_label=label[x_quantity], y_label=label[y_quantity], title=label["title"], ax=ax) # Get a reference to the experiment and its simulations experiment = get_experiment(research, experiment_id)[0] simulations = get_simulation(experiment, simulation_id) # The number of lines defines the colors so the colors of the lines change gradually with k color = get_lineColors(simulations, scan, k_fixed, k_range, plotted_modes) plot_i = 0 # Save the axis limits xlims = [0, 0] ylims = [0, 0] # Iterate over the simulations for simulation in simulations: # Get the modes of this simulation that need to be plotted vec_k = simulation.get_modesForAOneDimensionalScan( scan, k_fixed, k_range, plotted_modes) # Get the z and potential data from the simulation z_data = simulation.zeta if x_quantity == "zeta" else ( simulation.z_kxky if x_quantity == "z" else simulation.z_poloidal) y_data = simulation.phi_real if y_quantity == "phi_real" else ( simulation.phi_imag if y_quantity == "phi_imag" else simulation.phi2) # Iterate over the modes for k in vec_k: # Update the progress bar of the GUI if Progress: Progress.move( vec_k.index(k) / len(vec_k) * 100, "Plotting modes (" + str(vec_k.index(k)) + "/" + str(len(vec_k)) + ")") # Labels for the legend simulation_id = simulation.marker_label.replace('_', ' ') if isinstance(kx_range, float): label = "$k_y\\rho_i = " + "{0:.2f}".format(k) + "$" if isinstance(ky_range, float): label = "$k_x\\rho_i = " + "{0:.2f}".format(k) + "$" if len(simulations) > 1: label = label + ": " + simulation_id if len(vec_k) == 1: label = simulation_id # Get the z and potential data for this specific mode and remove the NaN and Inf values i_kx, i_ky = simulation.get_indicesOfMode(scan, k_fixed, k) vec_z = z_data[:, i_kx, i_ky][np.isfinite(y_data[:, i_kx, i_ky])] vec_y = y_data[:, i_kx, i_ky][np.isfinite(y_data[:, i_kx, i_ky])] # Plot the normalized potential since we are interested in the shape try: vec_y = vec_y / np.nanmax( [np.nanmax(vec_y), abs(np.nanmin(vec_y))]) except: print("Warning: The potential vector was empty.") # Plot omega(t) and gamma(t) ax.plot(vec_z, vec_y, lw=2, linestyle='-', color=color[plot_i], label=label, clip_on=False) plot_i += 1 # Keep track of the axis limits xlims = [min(z_data.min(), xlims[0]), max(z_data.max(), xlims[1])] ylims = [min(y_data.min(), ylims[0]), max(y_data.max(), ylims[1])] # If there were modes to be plotted, rescale and show the figure. if xlims != [0, 0] and ylims != [0, 0]: # Rescale the axis if x_range == None: x_range = xlims if y_range == None: y_range = [0, 1] if y_quantity == "phi2" else [-1, 1] rescale_axes(ax, x_range, y_range, units, font_size, handle_length) # Show the figure if we're not in a GUI if not root: plt.show() # If there were no modes, just clear the axis else: ax.clear() print("WARNING: There were no modes to be plotted.") # End if True: return
def plot_frequencyVsModes(\ # Specify which simulations to plot research=None,\ experiment_id="All experiments",\ simulation_id="All simulations",\ # Specify data range y_quantity='omega',\ x_range=None,\ y_range=None,\ # Details of the modes kx_range=-0.0, \ ky_range=[0,100], \ k_value=9.0, \ k_delta=1.0, \ plotted_modes="unstable",\ lineardata="average",\ # Labels x_label=None,\ y_label=None,\ title=None,\ # For the GUI the figure object already exists show_figure = False,\ ax=None, \ Progress=None,\ root=None,\ # Toggles units="normalized", \ show_error=False, \ maxima=False, \ interpolate=False): ''' Plot the frequency/omega or growthrate/gamma versus the wave number. Parameters ---------- research: object Contains the selected experiments and simulations. experiment_id, simulation_id: str Is used to select which simulations/experiments to plot. plotted_modes: {"unstable", "stable", "unconverged", "converged"} Determines which modes to plot. units: {"normalized", "SI units"} Determines the units of the data. lineardata: {"average", "last"} Either plot the last time value of omega/gamma or the average over the last 10% of time. ''' # Update the progress bar of the GUI if Progress: Progress.move(0,"Plot omega or gamma versus time.") # Decide whether to scan modes along the x-axis or y-axis scan, k_fixed, k_range = get_axisOfScan(kx_range, ky_range, root) if scan == False: return # Set the labels, and change the standard labels depending on the units label = determine_labels(x_label, y_label, kx_range, ky_range, title, units) load_plotbox2d(x_label=label['x'], y_label=label[y_quantity], title=label["title"], ax=ax) # Keep track of the labels that are already used and save the axis limits labels = []; xlims=[0,0]; ylims=[0,0]; # Get the experiments experiments = get_experiment(research, experiment_id) # Get the total number of varied values, to determine whether we need to use markers # to diferentiate between different simulations or whether the line colors are sufficient number_ofVariedValues = 0 for experiment in experiments: number_ofVariedValues = np.max([number_ofVariedValues,len(experiment.variedValues)]) # Iterate over the experiments for experiment in experiments: # Get the simulations simulations = get_simulation(experiment, simulation_id) # Iterate over the simulations for simulation in simulations: # Update the progress bar of the GUI if Progress: i = experiments.index(experiment)*len(simulations)+simulations.index(simulation); length=len(experiments)+len(simulations) if Progress: Progress.move(i/length*100,"Plotting spectra ("+str(i)+"/"+str(length)+")") # Get the modes of this simulation that need to be plotted and their indices in the (kx,ky) matrixes modes = simulation.get_modesForAOneDimensionalScan(scan, k_fixed, k_range, plotted_modes) i_kxky = simulation.get_indicesOfModes(scan, k_fixed, modes) # Get the omega or gamma at the last time value if y_quantity=="omega" and lineardata=="average": y_data = simulation.omega_avg[i_kxky] if y_quantity=="omega" and lineardata=="last": y_data = simulation.omega_last[i_kxky] if y_quantity=="gamma" and lineardata=="average": y_data = simulation.gamma_avg[i_kxky] if y_quantity=="gamma" and lineardata=="last": y_data = simulation.gamma_last[i_kxky] if y_quantity=="gamma/ky**2" and lineardata=="average": y_data = simulation.gamma_avg[i_kxky]/[m**2 for m in modes] if y_quantity=="gamma/ky**2" and lineardata=="last": y_data = simulation.gamma_last[i_kxky]/[m**2 for m in modes] # Initiate the errors on the calculation of omega/gamma at the last time step y_error = np.empty((2, len(modes))); y_error[:, :] = np.NaN # Get the error bars if y_quantity=="omega": y_error[0,:] = simulation.omega_min[i_kxky] if y_quantity=="omega": y_error[1,:] = simulation.omega_max[i_kxky] if y_quantity=="gamma": y_error[0,:] = simulation.gamma_min[i_kxky] if y_quantity=="gamma": y_error[1,:] = simulation.gamma_max[i_kxky] if y_quantity=="gamma/ky**2": y_error[0,:] = simulation.gamma_min[i_kxky]/[m**2 for m in modes] if y_quantity=="gamma/ky**2": y_error[1,:] = simulation.gamma_max[i_kxky]/[m**2 for m in modes] # Remove the Inf and Nan data points modes = np.array(modes)[np.isfinite(y_data)] y_error = y_error[:, np.isfinite(y_data)] y_data = y_data[np.isfinite(y_data)] # Plot the lines with the same color for each experiment if there are multiple experiments # or if we only varied 1 parameter since then we don't want to use any markers if len(modes)>0 and (len(experiments) > 1 or number_ofVariedValues==1): # Add a label to the legend for the first simulation of this experiment label_exp = experiment.line_label if simulations.index(simulation) == 0 else "" # If we interpolate, don't plot the lines lw = 2 if not interpolate else 0 # Plot the data ax.plot(-100, -100, lw=2, linestyle="-", color=experiment.line_color, label=label_exp) ax.plot(modes, y_data, lw=lw, linestyle="-", color=experiment.line_color) # Next plot the data points with the same color for each varied_value, to differentiate between simulations if len(modes)>0: # Add a label to the legend for the first simulation of this experiment label_var = simulation.marker_label label_var = label_var.replace("_"," ") if "$" not in label_var else label_var label_var = "" if (label_var in labels) else label_var; labels.append(label_var) marker_style = simulation.marker_style marker_color = simulation.marker_color # If there is only one experiment, add lines in the same color as the marker if not( (len(experiments) > 1) or (number_ofVariedValues==1) ): lw = 2 if (len(experiments) > 1) or (number_ofVariedValues==1) : lw = 0 if interpolate : lw = 0 # Plot the actual linear data points obtained by stella as markers (mfc = markerfacecolor; mec = markeredgecolor] ax.plot(modes, y_data, lw=lw ,linestyle='-', color=marker_color, ms=5 ,\ marker=marker_style, mec=marker_color, mfc=marker_color, label=label_var) # Add the error bars if show_error==True: print() print("Modes", experiment.id) print(y_error) ax.errorbar(modes, y_data, yerr=y_error, fmt='o', color=simulation.marker_color, capsize=2) # Calculate the maximum growth rate if interpolate or maxima: color = experiment.line_color if (len(experiments) > 1 or number_ofVariedValues==1) else marker_color plot_maximumGrowthrates(modes, y_data, y_quantity, ax, color, interpolate) # Keep track of the axis limits xlims = [np.nanmin([np.nanmin(modes), xlims[0]]), np.nanmax([1.1*np.nanmax(modes), xlims[1]])] ylims = [np.nanmin([np.nanmin(y_data), ylims[0]]), np.nanmax([1.1*np.nanmax(y_data), ylims[1]])] # Shade ky_range in the plot to indicate where the reflectometry machine measures. if k_value and k_delta and units=="SI units": ax.axvspan(k_value-k_delta, k_value+k_delta, alpha=0.5, color='navy') # Change appearance plot ax.autoscale() ax.set_title(title) ax.ticklabel_format(style='sci', scilimits=(0,0), axis='y') # Add the legend and sort its labels handles, labels = ax.get_legend_handles_labels() labels, handles = zip(*sorted(zip(labels, handles), key=lambda t: t[0])) ax.legend(handles, labels, loc='best',labelspacing=0.0, prop={'size':20}, framealpha=0.9) # Rescale the axis if x_range==None: x_range = xlims if y_range==None: y_range = ylims ax.set_xlim(x_range) ax.set_ylim(y_range) # Show the figure if show_figure: plt.show() return