diff --git a/Python_script/PostPlot.py b/Python_script/PostPlot.py index 487d26ee13c6b28d4c53487664be3d20df5480f1..fe71d54c94653b02c92055ef3445930d8e6e9fe7 100644 --- a/Python_script/PostPlot.py +++ b/Python_script/PostPlot.py @@ -6,12 +6,11 @@ Created on Tue Mar 7 10:15:55 2023 """ import pandas as pd -import matplotlib.pyplot as plt import sys from pathlib import Path import os -import numpy as np -from scipy.optimize import curve_fit +import MeasurementPlot +import time # after measurement has finished from stored csv-data a post plot of all temperature steps is plotted and store in @@ -24,6 +23,13 @@ class PostPlot: if 'ipykernel' in sys.modules: from IPython import get_ipython get_ipython().run_line_magic('matplotlib', 'qt') + + + self.postplot_obj = MeasurementPlot.MeasurementPlot(legend_loc = 'upper left', \ + legend_bbox_to_anchor = (1.09, 1)) + + # set parameter figure of class to object parameter figure + self.fig = self.postplot_obj.fig # read csv-file and import data to data frame def import_csv(self, csv_file): @@ -33,258 +39,68 @@ class PostPlot: return data_frame # plot function for data frame data, Michael - # labels for legend of external sensor is given in Parameterlist , Michael - # optinal calculation of regression, a plot of the fitted function and the calculation of correlation - # between DUT sensor Temperature and phase can be activated by parameterlist of function, michael - def plot_frame_data(self, data_frame, title ='', legend_sensor0 = ['Temperature Sensor0', 'Humidity Sensor0'], \ - legend_sensor1 = ['Temperature Sensor1','Humidity Sensor1', 'Air Pressure Sensor1'], \ - time_unit ='min', regression_state = False, plot_regression = False, plot_corr_coeff = False): - - # set label of plots with legend entries in parameter list of plot frame data method - label_temp_sensor0 = legend_sensor0[0] - label_hum_sensor0 = legend_sensor0[1] - - label_temp_sensor1 = legend_sensor1[0] - label_hum_sensor1 = legend_sensor1[1] - label_air_press_sensor1 = legend_sensor1[2] - - data_frame.reset_index(inplace=True, drop=True) - - # fetch plot data from data frame given in parameter list of function - timestamps = data_frame.TIMESTAMP - phases = data_frame.S21_PHASE - eq_indicator = data_frame.EQUILIBRIUM_INDICATOR - magnitudes = data_frame.S21_MAGNITUDE - temperatures = data_frame.READBACK_TEMPERATURE - humidities = data_frame.READBACK_HUMIDITY - temp_sensor0 = data_frame.TEMP_SENSOR0 - temp_sensor1 = data_frame.TEMP_SENSOR1 - hum_sensor0 = data_frame.HUM_SENSOR0 - hum_sensor1 = data_frame.HUM_SENSOR1 - air_press = data_frame.AIR_PRESSURE - temp_heater = data_frame.TEMP_HEATER - hum_heater = data_frame.HUM_HEATER + def plot_frame_data(self, data_frame, title ='', time_unit ='min'): - - # time stamp of list entry zero is the start point of time axis, Michael - # substract all other timestamps with list entry of zero to scale time axis, Michael - time_sec = timestamps - timestamps[0] - - # set scaling of time axis depending on the time unit given in parameter list, Michael - # default unit are minutes, Michael - time = self.scaling_time_axes(time_sec, time_unit) - - # calulate correlation betwenn trace of temp sensor 0 (DUT temeprature) and trace of the phase which is measured - # by VNA, Michael - corr_coeff_phase= np.corrcoef(phases, temp_sensor0)[0][1] - - # plot window with 5 subplots - self.fig, self.ax1 = plt.subplots(5, figsize=(25, 20)) + # set title of plot self.fig.suptitle("Measurement "+title, color="red") - # scale subplots to fit into space of figure so that axes labels and legends easily can be read, Michael - self.fig.subplots_adjust(bottom= 0.1, right=0.8, hspace = 0.4) - - minimum, maximum = self.get_extended_min_max(time) - self.ax1[0].set_xlim(minimum, maximum) - self.ax1[1].set_xlim(minimum, maximum) - # set x-axes limits for addinal plot equal to the plot for magnitude and phase of DUT, Michael - self.ax1[2].set_xlim(minimum, maximum) - self.ax1[3].set_xlim(minimum, maximum) - self.ax1[4].set_xlim(minimum, maximum) - # First plot: Phase and magnitude of DUT - self.path_collection_phase = self.ax1[0].scatter(time, phases, c='red', marker='<', label='DUT Phase') - minimum, maximum = self.get_extended_min_max(phases) - self.ax1[0].set_ylim(minimum, maximum) + # reset index of data frame + data_frame.reset_index(inplace=True, drop=True) - self.magnitude_axis = self.ax1[0].twinx() - self.path_collection_mag = self.magnitude_axis.scatter(time, magnitudes, c='#3120E0', marker='4', label='DUT Magnitude') - minimum, maximum = self.get_extended_min_max(magnitudes) - self.magnitude_axis.set_ylim(minimum, maximum) + # self.postplot_obj = MeasurementPlot.MeasurementPlot(legend_loc = 'upper left', \ + # legend_bbox_to_anchor = (1.09, 1)) - self.equi_axis0 = self.ax1[0].twinx() - # fix range to 0..31 with some extra margin for plotting - self.equi_axis0.set_ylim(-1, 32) - # increase outward position of axes for equilibrium indicator , Michael - self.equi_axis0.spines['right'].set_position(('outward', 75)) - self.path_collection_equi0 = self.equi_axis0.scatter(time, eq_indicator, c='black', marker=".", label='Equilibrium_Indicator') + # set y-Achlabel in all subplots to Time an in square brackets the selected time unit + for element in self.postplot_obj.ax1: + element.set_xlabel("Time [%s]" %time_unit) - if regression_state == True: - self.phase_t0 = phases[0] - self.K_phases = np.median(phases) - func, popt = self.choose_fit( time, phases) - annotate_string_fit = self.plot_fitted_func_param(func, *popt, time_unit = time_unit) - self.ax1[0].annotate(annotate_string_fit,xy=(0,min(phases)), xycoords='data', xytext=(-0.16,0),textcoords='axes fraction',fontsize = 16, horizontalalignment='left',verticalalignment='bottom') - if plot_regression == True: - fit_phaeses = func(time, *popt) - min_phases, max_phases = self.get_extended_min_max(phases) - min_fit_phases, max_fit_phases = self.get_extended_min_max(fit_phaeses) - minimum = min(min_phases, min_fit_phases) - maximum = max(max_phases, max_fit_phases) - self.ax1[0].set_ylim(minimum, maximum) - self.path_collection_curvefit = self.ax1[0].scatter(time, func(time, *popt), c='green', s = 1, marker = "." , label = 'fitted with\n' + func.__name__) - all_path_collections = [self.path_collection_phase, self.path_collection_mag, self.path_collection_equi0, self.path_collection_curvefit] - else: - all_path_collections = [self.path_collection_phase, self.path_collection_mag, self.path_collection_equi0] - else: - all_path_collections = [self.path_collection_phase, self.path_collection_mag, self.path_collection_equi0] - delta_phase = max(phases) - min(phases) - delta_magnitude = max(magnitudes) - min(magnitudes) - # plot delta values for phase and magnitude at left position outside the plot, Michael - annotate_string = "$\Delta\phi$($S_{21PkPk}$): %.3f °\n$\Delta$|$S_{21PkPk}$|: %.3f dB" % (delta_phase, delta_magnitude) - if plot_corr_coeff == True: - annotate_string +="\n" - annotate_string += "$R_{\phi(S_{21}),Temp_{DUT}}$ = %.3f" % corr_coeff_phase - self.ax1[0].annotate(annotate_string ,xy=(0,min(phases)), xycoords='data', xytext=(-0.16,1),textcoords='axes fraction',fontsize = 16, horizontalalignment='left',verticalalignment='bottom') + # make a copy of data_frame in parameterlist without changing original during modification + postplot_data_frame = data_frame.copy() - # units added to the y-axes labels, Michael - self.ax1[0].set_xlabel("TIME [%s]" %time_unit) - self.ax1[0].set_ylabel("PHASE [°]", color='red') - self.magnitude_axis.set_ylabel("MAGNITUDE [dB]", color='#3120E0') - # label of y-axis for equilibrium indicator is changed to Indiccator Value because it's shorter, Michael - self.equi_axis0.set_ylabel("INDICATOR VALUE", color='black') - - self.ax1[0].grid(True, linestyle=":") - labels = [pc.get_label() for pc in all_path_collections] + # time stamp of index = 0 is the start point of time axis, Michael + # substract all other timestamps with time stamp of index zero to get time scale in + # seconds, Michael + time_sec = postplot_data_frame.TIMESTAMP - postplot_data_frame.TIMESTAMP[0] - # set legend at rigth upper position outside subplot for phase and magnitude, Michael - self.ax1[0].legend(all_path_collections, labels, loc='upper left', bbox_to_anchor=(1.09, 1)) - - # Second plot: Humidity and temperature of climate chamber requested from internal sensors of climate chamber - self.path_collection_temp = self.ax1[1].scatter(time, temperatures, c='blue', marker='p', label="Chamber Temperature") - minimum, maximum = self.get_extended_min_max(temperatures) - self.ax1[1].set_ylim(minimum, maximum) + # set scaling of time axis depending on the time unit given in parameter list, Michael + # default unit is minutes, Michael + time = self.scaling_time_axes(time_sec, time_unit) - self.humidity_axis = self.ax1[1].twinx() - self.path_collection_hum = self.humidity_axis.scatter(time, humidities , c='green', marker="*", label="Chamber Humidity") - minimum, maximum = self.get_extended_min_max(humidities) - self.humidity_axis.set_ylim(minimum, maximum) + # update Timestamps with calculated time values + postplot_data_frame.update(time) - self.equi_axis1 = self.ax1[1].twinx() + # refresh subflots with data in data frame + self.postplot_obj.draw(postplot_data_frame, pdf_name = '') - # increase outward position of axes for equilibrium indicator , Michael - self.equi_axis1.spines['right'].set_position(('outward', 75)) - self.path_collection_equi1 = self.equi_axis1.scatter(time, eq_indicator, c='black', marker=".", label="Equilibrium_Indicator") - self.equi_axis1.set_ylim(-1, 32) - - # units added to the y-axes labels, Michael - self.ax1[1].set_xlabel("TIME [%s]" %time_unit) - self.ax1[1].set_ylabel("TEMPERATURE [°C] ", color='blue') - self.humidity_axis.set_ylabel("HUMIDITY [%RH]", color='green') - # label of y-axis for equilibrium indicator ist changed to Indiccator Value because it's shorter, Michael - self.equi_axis1.set_ylabel("INDICATOR VALUE", color='black') + # cal PK2PK values of magnitude and phase + PK2PK = self.calc_mag_phase_pkpk_values(data_frame) - - self.ax1[1].grid(True, linestyle=":") - all_path_collections = [self.path_collection_temp, self.path_collection_hum, self.path_collection_equi1] - labels = [pc.get_label() for pc in all_path_collections] - - # set legend at rigth upper position outside subplot for temperature and humidity from internal sensors of - # climate chamber, Michael - self.ax1[1].legend(all_path_collections, labels, loc='upper left', bbox_to_anchor=(1.09, 1)) + self.edit_annotation_in_plot(annotate_string = PK2PK) - # Third plot: temperatur external sensor0, humidity external sensors0, Michael - # sensor 0 is the sensor at port 0 of ahlborn and used for the DUT temperature, DUT humidity, Michael - # label for temeprature and humidity of sensor 0 can be configure by ext_sens_data.json, Michael + + def edit_annotation_in_plot(self, annotate_string ='', anno_fontsize = 16): - self.path_collection_temp_sensor0 = self.ax1[2].scatter(time,temp_sensor0, c='red', marker='p', label=label_temp_sensor0) - minimum, maximum = self.get_extended_min_max(temp_sensor0) - self.ax1[2].set_ylim(minimum, maximum) + # update text of annotation in first subplot + self.postplot_obj.annotation.set_text(annotate_string) - # second y-axis on the right for humidity of external sensor0 - self.ext_sens_hum_axis = self.ax1[2].twinx() - minimum, maximum = self.get_extended_min_max(hum_sensor0) - self.ext_sens_hum_axis.set_ylim(minimum, maximum) - self.path_collection_hum_sensor0 = self.ext_sens_hum_axis.scatter(time, hum_sensor0, c='purple', marker='*', label=label_hum_sensor0) + # edit annotation fontsize in first subplot + self.postplot_obj.annotation.set_fontsize(anno_fontsize) + + def calc_mag_phase_pkpk_values(self, data_frame): - # units added to the y-axes labels, Michael - self.ax1[2].set_xlabel("TIME [%s]" %time_unit) - self.ax1[2].set_ylabel("TEMPERATURE [°C]", color='red') - self.ext_sens_hum_axis.set_ylabel("HUMIDITY [%RH]", color = 'purple') - - self.ax1[2].grid(True, linestyle=":") - all_path_collections = [self.path_collection_temp_sensor0, self.path_collection_hum_sensor0] - labels = [pc.get_label() for pc in all_path_collections] + # calc PK2PK values of magnitude and phase + delta_phase = max(data_frame.S21_PHASE) - min(data_frame.S21_PHASE) + delta_magnitude = max(data_frame.S21_MAGNITUDE) - min(data_frame.S21_MAGNITUDE) - # set legend at rigth upper position outside subplot for temperature and humidity from external sensor 0, Michael - self.ax1[2].legend(all_path_collections, labels, loc='upper left', bbox_to_anchor=(1.09, 1)) - + # generate text for annoation in first subplot + delta_vals_string = "$\Delta\phi$($S_{21PkPk}$): %.3f °\n$\Delta$|$S_{21PkPk}$|: %.3f dB" \ + % (delta_phase, delta_magnitude) - # Forth plot: temperatur external sensor1, humidity external sensors1, air pressure external sensor1, Michael - # sensor 1 is the sensor at port 1 of ahlborn and used for the room temperature, the room humidity - # and the air pressure in the room, Michael - # label for temeprature and humidity of sensor0 can be configure by ext_sens_data.json, Michael - - self.path_collection_temp_sensor1 = self.ax1[3].scatter(time,temp_sensor1, c='green', marker='*', label=label_temp_sensor1) - minimum, maximum = self.get_extended_min_max(temp_sensor1) - self.ax1[3].set_ylim(minimum, maximum) - - # second y-axis on the right for humidity - self.sec_ext_hum_sens_axis = self.ax1[3].twinx() - minimum, maximum = self.get_extended_min_max(hum_sensor1) - self.sec_ext_hum_sens_axis.set_ylim(minimum, maximum) - self.path_collection_hum_sensor1 = self.sec_ext_hum_sens_axis.scatter(time,hum_sensor1, c='orange', marker='>', label=label_hum_sensor1) - - # third y-axis on the right for air pressure - self.press_axis = self.ax1[3].twinx() - self.press_axis.spines['right'].set_position(('outward', 60)) - minimum, maximum = self.get_extended_min_max(air_press) - self.press_axis.set_ylim(minimum, maximum) - self.path_collection_press = self.press_axis.scatter(time,air_press, c='grey', marker='4', label=label_air_press_sensor1) - - # units added to the y-axes labels, Michael - self.ax1[3].set_xlabel("TIME [%s]" %time_unit) - self.ax1[3].set_ylabel("TEMPERATURE [°C]", color='green') - self.sec_ext_hum_sens_axis.set_ylabel("HUMIDITY [%RH]", color = 'orange') - self.press_axis.set_ylabel("AIR PRESSURE [mb]", color ='grey') - - self.ax1[3].grid(True, linestyle=":") - all_path_collections = [self.path_collection_temp_sensor1, self.path_collection_hum_sensor1, \ - self.path_collection_press] - labels = [pc.get_label() for pc in all_path_collections] - # set legend at rigth upper position outside subplot for temperature and humidity from external sensor 1, Michael - self.ax1[3].legend(all_path_collections, labels, loc='upper left', bbox_to_anchor=(1.09, 1)) - - # Fifth plot: heater activity of temeprature heater and humidity heater - # values for activity are requested from climate chamber, Michael - - self.path_collection_temp_heater = self.ax1[4].scatter(time,temp_heater, c='black', marker='<', label='Temp Heater') - self.path_collection_hum_heater = self.ax1[4].scatter(time, hum_heater, c='brown', marker='o', label='Hum Heater') - - # get min max values for temperature heater and humdity heater, Michael - # select the lowest minimum and the highest maximum for limit of the y-axis, Michael - min_temp_heater, max_temp_heater = self.get_extended_min_max(temp_heater) - min_hum_heater, max_hum_heater = self.get_extended_min_max(hum_heater) - minimum = min(min_temp_heater, min_hum_heater) - maximum = max(max_temp_heater, max_hum_heater) - distance = maximum - minimum - - self.ax1[4].set_ylim(minimum-0.05*distance, maximum+0.05*(distance)) - - # units added to the y-axes labels, Michael - self.ax1[4].set_xlabel("TIME [%s]" %time_unit) - self.ax1[4].set_ylabel("HEATER PERCENTAGE [%]", color='black') - - self.ax1[4].grid(True, linestyle=":") - all_path_collections = [self.path_collection_temp_heater, \ - self.path_collection_hum_heater] - labels = [pc.get_label() for pc in all_path_collections] - # set legend at rigth upper position outside subplot for temperature heater and humidity heater, Michael - self.ax1[4].legend(all_path_collections, labels, loc='upper left', bbox_to_anchor=(1.08, 1)) - - # sclae fontsize of all plot window elements to size 14, Michael - plt.rcParams.update({'font.size':16}) - - # add 5 % of the distance between min and max to the range - @staticmethod - def get_extended_min_max(array): - distance = array.max() - array.min() - if distance == 0.: - distance = 1 - return array.min()-0.05*distance, array.max()+0.05*distance - + return delta_vals_string + + # save figure under the given storepath in parameterlist with the given filename in parameter list, Michael # file extension is part of filename, Michael def save_fig(self, storepath, filename): @@ -309,102 +125,16 @@ class PostPlot: return time - # step response of PT1 with initial behavior , Michael - def PT1(self, x, K, T1): - return K * (1 - np.exp(-x/T1)) + self.phase_t0 * np.exp(-x/T1) - - # step response of PT2 (D > 1) with initial behavior - def aperiodicPT2(self, x, K, T1, T2,): - return K + self.phase_t0* np.exp(-x/T1)/(T2-T1) - K *T1* np.exp(-x/T1)/(T2-T1) \ - - self.phase_t0 * np.exp(-x/T2)/(T2-T1) + K* T2* np.exp(-x/T2)/(T2-T1) - - # step response of PT2 (D = 1) with initial behavior, Michael - def aperiodic_borderPT2(self, x, K, T): - return K + self.phase_t0*np.exp(-x/T) - K * np.exp(-x/T) + self.phase_t0*np.exp(-x/T)*x/T + \ - - K * np.exp(-x/T) * x/T - - # step response of PT2 (0 < D < 1) with initial behavior, Michael - def periodicPT2(self, x, D, T): - return self.K_phases + (self.phase_t0 -self.K_phases)*np.exp(-D*x/T)*np.cos(np.sqrt(1-np.square(D))*x/T) + \ - (self.phase_t0 - self.K_phases) * D * np.exp(-D*x/T)*np.sin(np.sqrt(1-np.square(D))*x/T)/np.sqrt(1-np.square(D)) - - # step response series of PT2 ( D = 1) and PT1 with initial behavior, Michael - def aperiodic_borderPT2_PT1(self, x, a, b, c, d, T1, T2): - return a + b*np.exp(-x/T1)+c*x*np.exp(-x/T1) + d*np.exp(-x/T2) - - # method for cuvefit, Michael - # two different algorithms for curvefit are use depending on used step response for fit, Michael - def curvefit(self, func, time, phases): - if func.__name__ == 'periodicPT2': - popt, pcov = curve_fit(func, time, phases, method = 'trf', bounds = ([0.001, 0.001], [0.99, np.inf])) - else: - popt, pcov = curve_fit(func, time, phases, method = 'lm') - return popt, pcov - - # method adds the parameter of the fit with the lowest error to annotation string, Michael - # contens of annotation string is plotted on the left side of subplot 1 if regression state is activated, Michael - def plot_fitted_func_param(self, func, *popt, time_unit): + - if func.__name__ == 'PT1': - K = popt[0] - T1 = popt[1] - annotate_string = "K: %.2f\n$T_1$: %.3f %s" %(K, T1, time_unit) - elif func.__name__ == 'aperiodicPT2': - K = popt[0] - T1 = popt[1] - T2 = popt[2] - annotate_string = "K: %.2f\n$T_1$: %.3f %s\n$T_2$: %.3f %s" % (K, T1, time_unit, T2, time_unit) - elif func.__name__ == 'aperiodic_borderPT2': - K = popt[0] - T = popt[1] - annotate_string = "K: %.2f\nT: %.3f %s" %(K, T, time_unit) - elif func.__name__ == 'periodicPT2': - K = self.K_phases - D = popt[0] - T = popt[1] - T_2perc = 4*T/D - annotate_string = "K: %.2f\nD: %.3f\nT: %.3f %s\n$T_E$(2%%): %.2f %s" %(K, D, T, time_unit, T_2perc, time_unit) - elif func.__name__ == 'aperiodic_borderPT2_PT1': - T1 = popt[4] - T2 = popt[5] - annotate_string = "T_1$: %.3f %s\n$T_2$: %.3f %s" % (T1, time_unit, T2, time_unit) - else: - # default value - annotate_string ='' - return annotate_string - # calculates the fit for all step responses and calulates the lowest error, Michael - # parameter of the plot with the lowest error is returned by this function, Michael - # if curve fit fails for one stept response it takes the next one and plots in comman window the functions - # which failes, Michael - def choose_fit(self, time, phases): - popt = [] - perr = [] - used_functions = [] - functions = [self.PT1, self.aperiodic_borderPT2, self.aperiodicPT2, self.periodicPT2, \ - self.aperiodic_borderPT2_PT1] - for func in functions: - try: - # call curvefit method and put the fitted parameter for step response function to a list, Michael - popt.append(self.curvefit(func, time, phases)[0]) - # calculation of fitting error - perr.append(np.sqrt(np.square(np.subtract(phases, func(time, *popt[-1]))).mean())) - used_functions.append(func) - except RuntimeError: - print('curvefit of %s fails' %func.__name__) - # get position of parameters in list which has the lowest calculated error, Michael - pos = perr.index(min(perr)) - # return function name and parameter with the lowest calculated error during curvefit, Michael - return used_functions[pos], popt[pos] - # for manually redo post plot after measurement has finished, Michael if __name__ == '__main__': + # set result path for post plot - Results_Path = r'C:\Users\pawelzik\Desktop\Results\THRU_27032023' + Results_Path = r'C:\Users\pawelzik\Desktop\Results\THRU_27032023Copy' - # activate/deactivate calculation of regression with PT1 - PT3 elements, Michael - regression_state = False # set time unit for post post plot # default is minutes if entry in parameterlist left empty @@ -417,13 +147,13 @@ if __name__ == '__main__': # search all csv files in results folder csv_file_list = list(Path(Results_Path).glob("**/*.csv")) - # set entires for the external sensors of ahlborn in legend of plot windows - legend_sensor0=['TEMP-Sensor DUT', 'HUM-Sensor DUT'] - legend_sensor1 = ['Room Temperature','Room Humidity', 'Air Pressure Room'] # create postplot object, Michael plot_obj = PostPlot() + # empty data frame for concat the data frames from csv import to plot full transistion + concat_data_frame = pd.DataFrame() + # plot results for each csv-file for index, csv_file in enumerate(csv_file_list): @@ -433,38 +163,27 @@ if __name__ == '__main__': # determine title of plot from csv-filename, Michael title = csv_file.name - if index < 1: - - # set concate data frame to first dataframe in list, Michael - concate_data_frame = data_frame - - # call post plot method, Michael + # concate datesframe for plotting full transistion data + concat_data_frame = pd.concat([concat_data_frame,data_frame],ignore_index=True, sort = False) - plot_obj.plot_frame_data(data_frame, title,legend_sensor0, legend_sensor1, time_unit, \ - regression_state = False, plot_regression = True, plot_corr_coeff = False) - - else: - - concate_data_frame = concate_data_frame.append(data_frame) - plot_obj.plot_frame_data(data_frame, title,legend_sensor0, legend_sensor1, time_unit, \ - regression_state, plot_regression = True) - + plot_obj.plot_frame_data(data_frame, title, time_unit) # set filename of post plot, Michael - filename = str(csv_file.stem) + '.svg' + filename = str(csv_file.stem) + '.pdf' - # store post plot under the path taht is set in storepath with the earlier defined filename, Michael + # store post plot under the path taht is set in storepath with the earlier defined filename plot_obj.save_fig(storepath, filename) - + + # plot of all steps of a sweep is plotted in one diagram, Michael # title of this plot will be always full transistion, Michel - # legend for external sensors is steh to the pre defined values of lgend_snesor0 and legend_sensor1, Michael - plot_obj.plot_frame_data(concate_data_frame, 'Full Transistion', legend_sensor0, legend_sensor1, time_unit) + plot_obj.plot_frame_data(concat_data_frame, 'Full Transistion', time_unit) + # filename of plot that contains all steps of sweep is set to FullTransistion, Michael - filename = 'Full_Transistion' + '.svg' + filename = 'Full_Transistion' + '.pdf' # plot with the results of all steps is store under the predefined storpath with the earlier defined filename, Michael plot_obj.save_fig(storepath, filename) - \ No newline at end of file + \ No newline at end of file