def plot_full_render(self, first_render, wave_data_dict, plot_data_state, plot_data_mol, plot_data_concentration, n_steps, vessels: vessel.Vessel, step_num): ''' Method to plot thermodynamic variables and spectral data. Plots a significant amount of data for a more in-depth understanding of the information portrayed. Parameters --------------- `first_render` : `boolean` Indicates whether a plot has been already rendered `wave_data_dict` : `dict` A dictionary containing all the wave data `plot_data_state` : `list` A list containing the states to be plotted such as time, temperature, volume, pressure, and reactant amounts `plot_data_mol` : `list` A list containing the molar amounts of reactants and products `plot_data_concentration` : `list` A list containing the concentration of reactants and products `n_steps` : `int` The number of increments into which the action is split `vessels` : `vessel.Vessel` A vessel containing methods to obtain thermodynamic data `step_num` : `int` The step number the environment is currently on Returns --------------- None Raises --------------- None ''' num_list = [ plot_data_state[0][0], plot_data_state[1][0], plot_data_state[2][0], plot_data_state[3][0] ] + self.get_ni_num() reactants = [] for reactant in self.reactants: name = reactant.replace("[", "").replace("]", "") short_name = name[0:5] reactants.append(short_name) label_list = ['t', 'T', 'V', 'P'] + reactants spectra_len = wave_data_dict["spectra_len"] absorb = wave_data_dict["absorb"] wave = wave_data_dict["wave"] wave_min = wave_data_dict["wave_min"] wave_max = wave_data_dict["wave_max"] peak = CharacterizationBench().get_spectra_peak( vessels, materials=self.materials) dash_spectra = CharacterizationBench().get_dash_line_spectra( vessels, materials=self.materials) # The first render is required to initialize the figure if first_render: plt.close('all') plt.ion() self._plot_fig, self._plot_axs = plt.subplots(3, 3, figsize=(24, 12)) # Time vs. Molar_Amount graph ********************** Index: (0, 0) self._plot_lines_amount = np.zeros((self.n.shape[0], 2, 20)) for i in range(self.n.shape[0]): self._plot_lines_amount[i][0][step_num - 1:] = (plot_data_state[0][0]) self._plot_lines_amount[i][1][step_num - 1:] = (plot_data_mol[i][0]) self._plot_axs[0, 0].plot(self._plot_lines_amount[i][0], self._plot_lines_amount[i][1], label=self.materials[i]) self._plot_axs[0, 0].set_xlim( [0.0, vessels.get_defaultdt() * n_steps]) self._plot_axs[0, 0].set_ylim([0.0, np.mean(plot_data_mol)]) self._plot_axs[0, 0].set_xlabel('Time (s)') self._plot_axs[0, 0].set_ylabel('Molar Amount (mol)') self._plot_axs[0, 0].legend() # Time vs. Molar_Concentration graph *************** Index: (0, 1) self._plot_lines_concentration = np.zeros((self.n.shape[0], 2, 20)) total_conc = 0 for i in range(self.n.shape[0]): total_conc += plot_data_concentration[i][0] for i in range(self.n.shape[0]): self._plot_lines_concentration[i][0][step_num - 1:] = ( plot_data_state[0][0]) self._plot_lines_concentration[i][1][step_num - 1:] = ( plot_data_concentration[i][0]) self._plot_axs[0, 1].plot(self._plot_lines_concentration[i][0], self._plot_lines_concentration[i][1], label=self.materials[i]) self._plot_axs[2, 0].plot( self._plot_lines_concentration[i][0], self._plot_lines_concentration[i][1] / total_conc, label=self.materials[i]) self._plot_axs[0, 1].set_xlim( [0.0, vessels.get_defaultdt() * n_steps]) self._plot_axs[0, 1].set_ylim([0.0, np.mean(plot_data_concentration)]) self._plot_axs[0, 1].set_xlabel('Time (s)') self._plot_axs[0, 1].set_ylabel('Molar Concentration (mol/L)') self._plot_axs[0, 1].legend() # Time vs. Temperature + Time vs. Volume graph *************** Index: (0, 2) self._plot_lines_temp = np.zeros((1, 2, 20)) self._plot_lines_temp[0][0][step_num - 1:] = (plot_data_state[0][0]) self._plot_lines_temp[0][1][step_num - 1:] = (plot_data_state[1][0]) self._plot_axs[0, 2].plot(self._plot_lines_temp[0][0], self._plot_lines_temp[0][1], label='T') self._plot_lines_vol = np.zeros((1, 2, 20)) self._plot_lines_vol[0][0][step_num - 1:] = (plot_data_state[0][0]) self._plot_lines_vol[0][1][step_num - 1:] = (plot_data_state[2][0]) self._plot_axs[0, 2].plot(self._plot_lines_vol[0][0], self._plot_lines_vol[0][1], label='V') self._plot_axs[0, 2].set_xlim( [0.0, vessels.get_defaultdt() * n_steps]) self._plot_axs[0, 2].set_ylim([0, 1.2]) self._plot_axs[0, 2].set_xlabel('Time (s)') self._plot_axs[0, 2].set_ylabel('T and V (map to range [0, 1])') self._plot_axs[0, 2].legend() # Time vs. Pressure graph *************** Index: (1, 0) self._plot_lines_pressure = np.zeros((1, 2, 20)) self._plot_lines_pressure[0][0][step_num - 1:] = (plot_data_state[0][0]) self._plot_lines_pressure[0][1][step_num - 1:] = (plot_data_state[3][0]) self._plot_axs[1, 0].plot(self._plot_lines_pressure[0][0], self._plot_lines_pressure[0][1], label='V') self._plot_axs[1, 0].set_xlim( [0.0, vessels.get_defaultdt() * n_steps]) self._plot_axs[1, 0].set_ylim([0, vessels.get_pmax()]) self._plot_axs[1, 0].set_xlabel('Time (s)') self._plot_axs[1, 0].set_ylabel('Pressure (kPa)') # Solid Spectra graph *************** Index: (1, 1) __ = self._plot_axs[1, 1].plot( wave, # wavelength space (ranging from wave_min to wave_max) absorb # absorb spectra )[0] # dash spectra for spectra in dash_spectra: self._plot_axs[1, 1].plot(wave, spectra, linestyle='dashed') # include the labelling when plotting spectral peaks for i in range(len(peak)): self._plot_axs[1, 1].scatter(peak[i][0], peak[i][1], label=peak[i][2]) self._plot_axs[1, 1].set_xlim([wave_min, wave_max]) self._plot_axs[1, 1].set_ylim([0, 1.2]) self._plot_axs[1, 1].set_xlabel('Wavelength (nm)') self._plot_axs[1, 1].set_ylabel('Absorbance') self._plot_axs[1, 1].legend() # bar chart plotting the time, tempurature, pressure, and amount of each # species left in hand *************** Index: (1, 2) __ = self._plot_axs[1, 2].bar(range(len(num_list)), num_list, tick_label=label_list)[0] self._plot_axs[1, 2].set_ylim([0, 1]) self._plot_axs[2, 0].set_xlim( [0.0, vessels.get_defaultdt() * n_steps]) self._plot_axs[2, 0].set_ylim([0.0, 1.0]) self._plot_axs[2, 0].set_xlabel('Time (s)') self._plot_axs[2, 0].set_ylabel('Purity') self._plot_axs[2, 0].legend() # draw and show the full graph self._plot_fig.canvas.draw() plt.show() # All other renders serve to update the existing figure with the new current state; # it is assumed that the above actions have already been carried out else: # set data for the Time vs. Molar_Amount graph *************** Index: (0, 0) curent_time = plot_data_state[0][-1] # update the lines data total_conc = 0 for i in range(self.n.shape[0]): total_conc += plot_data_concentration[i][0] for i in range(self.n.shape[0]): # populate the lines amount array with the updated number of mols self._plot_lines_amount[i][0][step_num - 1:] = (plot_data_state[0][0]) self._plot_lines_amount[i][1][step_num - 1:] = (plot_data_mol[i][0]) self._plot_axs[0, 0].lines[i].set_xdata( self._plot_lines_amount[i][0]) self._plot_axs[0, 0].lines[i].set_ydata( self._plot_lines_amount[i][1]) # populate the lines concentration array with the updated number of concentration self._plot_lines_concentration[i][0][step_num - 1:] = ( plot_data_state[0][0]) self._plot_lines_concentration[i][1][step_num - 1:] = ( plot_data_concentration[i][0]) self._plot_axs[0, 1].lines[i].set_xdata( self._plot_lines_concentration[i][0]) self._plot_axs[0, 1].lines[i].set_ydata( self._plot_lines_concentration[i][1]) self._plot_axs[2, 0].lines[i].set_xdata( self._plot_lines_concentration[i][0]) self._plot_axs[2, 0].lines[i].set_ydata( self._plot_lines_concentration[i][1] / total_conc) # reset each plot's x-limit because the latest action occurred at a greater time-value self._plot_axs[0, 0].set_xlim([0.0, curent_time]) self._plot_axs[0, 1].set_xlim([0.0, curent_time]) # reset each plot's y-limit in order to fit and show all materials on the graph self._plot_axs[0, 0].set_ylim([0.0, np.mean(plot_data_mol)]) self._plot_axs[0, 1].set_ylim([0.0, np.mean(plot_data_concentration)]) # set data for Time vs. Temp and Time vs. Volume graphs *************** Index: (0, 2) self._plot_lines_temp[0][0][step_num - 1:] = (plot_data_state[0][0]) self._plot_lines_temp[0][1][step_num - 1:] = (plot_data_state[1][0]) self._plot_lines_vol[0][0][step_num - 1:] = (plot_data_state[0][0]) self._plot_lines_vol[0][1][step_num - 1:] = (plot_data_state[2][0]) self._plot_axs[0, 2].lines[0].set_xdata(self._plot_lines_temp[0][0]) self._plot_axs[0, 2].lines[0].set_ydata(self._plot_lines_temp[0][1]) self._plot_axs[0, 2].lines[1].set_xdata(self._plot_lines_vol[0][0]) self._plot_axs[0, 2].lines[1].set_ydata(self._plot_lines_vol[0][1]) # reset xlimit since t extend self._plot_axs[0, 2].set_xlim([0.0, curent_time]) # set data for Time vs. Pressure graph *************** Index: (1, 0) self._plot_lines_pressure[0][0][step_num - 1:] = (plot_data_state[0][0]) self._plot_lines_pressure[0][1][step_num - 1:] = (plot_data_state[3][0]) self._plot_axs[1, 0].lines[0].set_xdata( self._plot_lines_pressure[0][0]) self._plot_axs[1, 0].lines[0].set_ydata( self._plot_lines_pressure[0][1]) self._plot_axs[1, 0].set_xlim([0.0, curent_time ]) # reset xlime since t extend self._plot_axs[1, 0].set_ylim([0.0, np.max(plot_data_state[3]) * 1.1]) # reset the Solid Spectra graph self._plot_axs[1, 1].cla() __ = self._plot_axs[1, 1].plot( wave, # wavelength space (ranging from wave_min to wave_max) absorb, # absorb spectra )[0] # obtain the new dash spectra data for __, item in enumerate(dash_spectra): self._plot_axs[1, 1].plot(wave, item, linestyle='dashed') # reset the spectra peak labelling for i in range(len(peak)): self._plot_axs[1, 1].scatter(peak[i][0], peak[i][1], label=peak[i][2]) self._plot_axs[1, 1].set_xlim([wave_min, wave_max]) self._plot_axs[1, 1].set_ylim([0, 1.2]) self._plot_axs[1, 1].set_xlabel('Wavelength (nm)') self._plot_axs[1, 1].set_ylabel('Absorbance') self._plot_axs[1, 1].legend() # bar chart self._plot_axs[1, 2].cla() __ = self._plot_axs[1, 2].bar( range(len(num_list)), num_list, tick_label=label_list, )[0] self._plot_axs[1, 2].set_ylim([0, 1]) # re-draw the graph self._plot_fig.canvas.draw() plt.pause(0.000001)
def plotting_step(self, t, tmax, vessels: vessel.Vessel): ''' Set up a method to handle the acquisition of the necessary plotting parameters from an input vessel. Parameters --------------- `t` : `float` Current amount of time `tmax` : `float` Maximum time allowed `vessels` : `vessel.Vessel` A vessel containing methods to acquire the necessary parameters Returns --------------- `plot_data_state` : `list` A list containing the states to be plotted such as time, temperature, volume, pressure, and reactant amounts `plot_data_mol` : `list` A list containing the molar amounts of reactants and products `plot_data_concentration` : `list` A list containing the concentration of reactants and products Raises --------------- None ''' # acquire the necessary parameters from the vessel T = vessels.get_temperature() V = vessels.get_volume() # V = 0.0025 # create containers to hold the plotting parameters plot_data_state = [[], [], [], []] plot_data_mol = [[] for _ in range(self.n.shape[0])] plot_data_concentration = [[] for _ in range(self.n.shape[0])] # Record time data plot_data_state[0].append(t / tmax) # record temperature data Tmin = vessels.get_Tmin() Tmax = vessels.get_Tmax() plot_data_state[1].append((T - Tmin) / (Tmax - Tmin)) # record volume data Vmin = vessels.get_min_volume() Vmax = vessels.get_max_volume() plot_data_state[2].append((V - Vmin) / (Vmax - Vmin)) # record pressure data P = vessels.get_pressure() plot_data_state[3].append(P / vessels.get_pmax()) # calculate and record the molar concentrations of the reactants and products C = vessels.get_concentration(materials=self.materials) for j in range(self.n.shape[0]): plot_data_mol[j].append(self.n[j]) plot_data_concentration[j].append(C[j]) return plot_data_state, plot_data_mol, plot_data_concentration