Skip to content
Snippets Groups Projects
Commit dbc09a89 authored by Michael Pawelzik's avatar Michael Pawelzik
Browse files

- Analysis Plot and Post Plot separated

- new function ins post plot for plotting analysis parameter
- PlotData from Test of modules added
parent 677e3f19
No related branches found
No related tags found
1 merge request!3feat: introduce external sensors
Showing with 190 additions and 117 deletions
......@@ -9,8 +9,9 @@ import pandas as pd
import sys
from pathlib import Path
import os
import MeasurementPlot
import curvefit_and_correlation
from MeasurementPlot import MeasurementPlot
import numpy as np
# after measurement has finished from stored csv-data a post plot of all temperature steps is plotted and store in
......@@ -18,18 +19,22 @@ import curvefit_and_correlation
# oftional correclation and regression can be calculated and plotted in results, Michael
# option is configureable via ext_sens_data.json, Michael
class PostPlot:
def __init__(self, env_cond_sensors = ''):
def __init__(self, env_cond_sensors = '', legend_loc = 'upper left', \
legend_bbox_to_anchor = (1.09, 1)):
# set python for opening an separate plot window
if 'ipykernel' in sys.modules:
from IPython import get_ipython
get_ipython().run_line_magic('matplotlib', 'qt')
self.measplot_obj = MeasurementPlot.MeasurementPlot(env_cond_sensors = env_cond_sensors,\
legend_loc = 'upper left', legend_bbox_to_anchor = (1.09, 1))
self.measplot = MeasurementPlot(env_cond_sensors = env_cond_sensors,\
legend_loc = legend_loc, legend_bbox_to_anchor = legend_bbox_to_anchor)
self.legend_loc = legend_loc
self.legend_bbox_to_anchor = legend_bbox_to_anchor
# set parameter figure of class to object parameter figure
self.fig = self.measplot_obj.fig
self.fig = self.measplot.fig
# read csv-file and import data to data frame
def import_csv(self, csv_file):
......@@ -48,7 +53,7 @@ class PostPlot:
data_frame.reset_index(inplace=True, drop=True)
# set y-Achlabel in all subplots to Time an in square brackets the selected time unit
for element in self.measplot_obj.ax1:
for element in self.measplot.ax1:
element.set_xlabel("Time [%s]" %time_unit)
# make a copy of data_frame in parameterlist without changing original during modification
......@@ -67,7 +72,7 @@ class PostPlot:
postplot_data_frame.update(time_vals)
# refresh subflots with data in data frame
self.measplot_obj.draw(postplot_data_frame, pdf_name = '')
self.measplot.draw(postplot_data_frame, pdf_name = '')
# cal PK2PK values of magnitude and phase
PK2PK = self.calc_mag_phase_pkpk_values(data_frame)
......@@ -78,13 +83,12 @@ class PostPlot:
def edit_annotation_in_plot(self, annotate_string ='', anno_fontsize = 16):
self.fig
# update text of annotation in first subplot
self.measplot_obj.annotation.set_text(annotate_string)
self.measplot.annotation.set_text(annotate_string)
# edit annotation fontsize in first subplot
self.measplot_obj.annotation.set_fontsize(anno_fontsize)
self.measplot.annotation.set_fontsize(anno_fontsize)
def calc_mag_phase_pkpk_values(self, data_frame):
......@@ -98,7 +102,38 @@ class PostPlot:
return delta_vals_string
def add_curvefit_to_plot(self, y_lim = None , xvals = [], yvals = [], \
trace_color = 'None', trace_label = ''):
if y_lim != None:
# set axis for phaseplot to min, max values
self.measplot.ax1[0].set_ylim(y_lim)
# set color of trace for curvefit result to green (trace is visible)
self.measplot.path_collection_fit.set_color(trace_color)
# set label of trace curvefit results to name of fit function name
self.measplot.path_collection_fit.set_label(trace_label)
# refrest data in meas plot
self.measplot.path_collection_fit.set_offsets(np.c_[xvals, yvals])
# get legend handles and labels y-axes from subplot magnitude, phase
handles_phase, labels_phase = self.measplot.ax1[0].get_legend_handles_labels()
handles_mag, labels_mag = self.measplot.magnitude_axis.get_legend_handles_labels()
handles_equi0, labels_eqi0 = self.measplot.equi_axis0.get_legend_handles_labels()
handles = handles_phase + handles_mag + handles_equi0
labels = labels_phase + labels_mag + labels_eqi0
# update legend subplot phase, magnitude
self.measplot.ax1[0].legend(handles, labels, loc = self.legend_loc, \
bbox_to_anchor = self.legend_bbox_to_anchor)
# refresh plot window
self.measplot.fig.canvas.flush_events()
# 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):
......@@ -140,26 +175,17 @@ if __name__ == '__main__':
time_unit = 'min'
# set storepath for the post plots, Michael
storepath = Results_Path + '\\Plots'
storepath = Results_Path + '\\PostPlots'
# search all csv files in results folder
csv_file_list = list(Path(Results_Path).glob("**/*.csv"))
# choose annotation option
plot_correlation_coeff = False
plot_regression_coeff = False
# activate plot curvefitting
plot_trace_curvefit = False
trace_selection = ""
# create postplot object, Michael
plot_obj = PostPlot(env_cond_sensors= trace_selection)
fit_corr_obj = curvefit_and_correlation.reg_and_corr(plot_obj)
# empty data frame for concat the data frames from csv import to plot full transistion
concat_data_frame = pd.DataFrame()
......@@ -178,34 +204,9 @@ if __name__ == '__main__':
# plot frame data
plot_obj.plot_frame_data(data_frame, title, time_unit)
plot_obj.plot_frame_data(data_frame, title, time_unit)
if plot_correlation_coeff == True:
# determine correlation coefficient between func 1 and func 2
corr_coeff =fit_corr_obj.calc_correlation(func_1 = data_frame.S21_PHASE , \
func_2 = data_frame.TEMP_DUT)
# plot correlation coefficient
plot_obj.edit_annotation_in_plot(annotate_string = corr_coeff)
elif plot_regression_coeff == True:
# start curvefit and determine coefficients best fit function
reg_coeff = fit_corr_obj.calc_regression_coeff_phase_S21(data_frame, time_unit = 'min')
# plot regression coefficients
plot_obj.edit_annotation_in_plot(annotate_string = reg_coeff)
plot_obj.edit_annotation_in_plot(annotate_string = reg_coeff)
if plot_trace_curvefit == True:
fit_corr_obj.plot_phase_curve_fit(data_frame = data_frame, \
postplot_obj = plot_obj.measplot_obj, \
time_unit = time_unit, state = True)
# set filename of post plot, Michael
filename = str(csv_file.stem) + '.pdf'
......@@ -217,10 +218,6 @@ if __name__ == '__main__':
# title of this plot will be always full transistion, Michel
plot_obj.plot_frame_data(concat_data_frame, 'Full Transistion', time_unit)
fit_corr_obj.plot_phase_curve_fit(data_frame = concat_data_frame, \
postplot_obj = plot_obj.measplot_obj, \
time_unit = time_unit, state = False)
# filename of plot that contains all steps of sweep is set to FullTransistion, Michael
filename = 'Full_Transistion' + '.pdf'
......
File added
File added
File added
File added
File added
File added
......@@ -6,56 +6,65 @@ Created on Thu Jul 27 08:53:36 2023
"""
import numpy as np
from scipy.optimize import curve_fit
from PostPlot import PostPlot
import pandas as pd
from pathlib import Path
class reg_and_corr:
def __init__(self, post_plot_obj, legend_loc = 'upper left', \
def __init__(self, env_cond_sensors = '', legend_loc = 'upper left', \
legend_bbox_to_anchor = (1.09, 1)):
self.post_plot_obj = post_plot_obj
self.postplot = PostPlot(env_cond_sensors = env_cond_sensors)
self.K_phases = None
self.phase_t0 = None
self.legend_loc = legend_loc
self.legend_bbox_to_anchor = legend_bbox_to_anchor
def calc_correlation(self, func_1 , func_2 , state = 'False'):
# calulate correlation between two parameter from data frame
corr_coeff= np.corrcoef(func_1, func_2)[0][1]
annotate_string = "$R_{\phi(S_{21}),Temp_{DUT}}$ = %.3f" % corr_coeff
return annotate_string
if state == True:
# calulate correlation between two parameter from data frame
corr_coeff= np.corrcoef(func_1, func_2)[0][1]
annotate_string_corr_coeff = "$R_{\phi(S_{21}),Temp_{DUT}}$ = %.3f" % corr_coeff
self.postplot.edit_annotation_in_plot(annotate_string_corr_coeff)
def calc_regression_coeff_phase_S21(self, data_frame, time_unit = 'min', state = False):
phases = data_frame.S21_PHASE.tolist()
self.phase_t0 = phases[0]
self.K_phases = np.median(data_frame.S21_PHASE)
# 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 = data_frame.TIMESTAMP - data_frame.TIMESTAMP[0]
# set scaling of time axis depending on the time unit given in parameter list, Michael
# default unit is minutes, Michael
time_vals = self.scaling_time_axes(time_sec, time_unit)
func, popt = self.choose_fit(time_vals, data_frame.S21_PHASE)
annotate_string_fit = self.plot_fitted_func_param(func, *popt, time_unit = time_unit)
if state == True:
phases = data_frame.S21_PHASE.tolist()
self.phase_t0 = phases[0]
self.K_phases = np.median(data_frame.S21_PHASE)
# 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 = data_frame.TIMESTAMP - data_frame.TIMESTAMP[0]
# set scaling of time axis depending on the time unit given in parameter list, Michael
# default unit is minutes, Michael
time_vals = self.scaling_time_axes(time_sec, time_unit)
func, popt = self.choose_fit(time_vals, data_frame.S21_PHASE)
annotate_string_reg_coeff = self.plot_fitted_func_param(func, *popt, time_unit = time_unit)
self.postplot.edit_annotation_in_plot(annotate_string_reg_coeff)
return annotate_string_fit
def plot_phase_curve_fit(self, data_frame, postplot_obj, time_unit = 'min', state = False):
def plot_phase_curve_fit(self, data_frame, time_unit = 'min', state = False):
if state == True:
phases = data_frame.S21_PHASE.tolist()
self.phase_t0 = phases[0]
......@@ -90,41 +99,18 @@ class reg_and_corr:
# determine max of measured phases and max of curvefit
maximum = max(max_phases, max_fit_phases)
# set axis for phaseplot to min, max values
postplot_obj.ax1[0].set_ylim(minimum, maximum)
# set color of trace for curvefit result to green (trace is visible)
postplot_obj.path_collection_fit.set_color('green')
# set label of trace curvefit results to name of fit function name
postplot_obj.path_collection_fit.set_label('fitted with\n' + func.__name__)
postplot_obj.path_collection_fit.set_offsets(np.c_[time_vals, func(time_vals, *popt)])
self.postplot.add_curvefit_to_plot(xvals =time_vals, \
yvals = func(time_vals, *popt), \
y_lim =[minimum, maximum], \
trace_color = 'green', \
trace_label = 'fitted by\n' + func.__name__)
else:
# set color of trace for curvefit result to None (trace is invisible)
postplot_obj.path_collection_fit.set_color('None')
# set label of trace curvefit results to '' (no label)
postplot_obj.path_collection_fit.set_label('')
# get legend handles and labels y-axes from subplot magnitude, phase
handles_phase, labels_phase = postplot_obj.ax1[0].get_legend_handles_labels()
handles_mag, labels_mag = postplot_obj.magnitude_axis.get_legend_handles_labels()
handles_equi0, labels_eqi0 = postplot_obj.equi_axis0.get_legend_handles_labels()
handles = handles_phase + handles_mag + handles_equi0
labels = labels_phase + labels_mag + labels_eqi0
# update legend subplot phase, magnitude
postplot_obj.ax1[0].legend(handles, labels, loc = postplot_obj.legend_loc, \
bbox_to_anchor = postplot_obj.legend_bbox_to_anchor)
# refresh plot window
postplot_obj.fig.canvas.draw()
postplot_obj.fig.canvas.flush_events()
self.postplot.add_curvefit_to_plot(xvals =[], \
yvals = [], \
y_lim = None, \
trace_color = 'None', \
trace_label = '')
......@@ -250,5 +236,95 @@ class reg_and_corr:
if distance == 0.:
distance = 1
return array.min()-0.05*distance, array.max()+0.05*distance
# for manually redo post plot after measurement has finished and insert analysis function, Michael
if __name__ == '__main__':
# set result path for post plot
Results_Path = r'C:\git\climate-lab-test-stand\Python_script\TestData_JBY240'
# set time unit for post post plot
# default is minutes if entry in parameterlist left empty
# possible entries: 'min' for minutes, 'hours' for hours and 'sec' for seconds
time_unit = 'min'
# set storepath for the post plots, Michael
storepath = Results_Path + '\\AnalysisPlots'
# search all csv files in results folder
csv_file_list = list(Path(Results_Path).glob("**/*.csv"))
# choose annotation option
plot_correlation_coeff = False
plot_regression_coeff = False
# activate plot curvefitting
plot_trace_curvefit = True
trace_selection = ""
# create postplot object, Michael
analysisplot_obj = reg_and_corr(env_cond_sensors= trace_selection)
# 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):
# import csv-data from csv-files in list, Michael
data_frame = analysisplot_obj.postplot.import_csv(str(csv_file))
# determine title of plot from csv-filename, Michael
title = csv_file.name
# concate datesframe for plotting full transistion data
concat_data_frame = pd.concat([concat_data_frame,data_frame],ignore_index=True, sort = False)
# plot frame data
analysisplot_obj.postplot.plot_frame_data(data_frame, title, time_unit)
# determine correlation coefficient between func 1 and func 2 and plot coefficient
analysisplot_obj.calc_correlation(func_1 = data_frame.S21_PHASE , \
func_2 = data_frame.TEMP_DUT, state = plot_correlation_coeff )
# start curvefit and determine coefficients best fit function and plot coefficients
analysisplot_obj.calc_regression_coeff_phase_S21(data_frame, time_unit = 'min', \
state = plot_regression_coeff)
analysisplot_obj.plot_phase_curve_fit(data_frame = data_frame, time_unit = time_unit, \
state = plot_trace_curvefit)
# set filename of post plot, Michael
filename = str(csv_file.stem) + '.pdf'
# store post plot under the path taht is set in storepath with the earlier defined filename
analysisplot_obj.postplot.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
analysisplot_obj.postplot.plot_frame_data(concat_data_frame, 'Full Transistion', time_unit)
analysisplot_obj.plot_phase_curve_fit(data_frame = concat_data_frame, time_unit = time_unit, \
state = False)
# filename of plot that contains all steps of sweep is set to FullTransistion, Michael
filename = 'Full_Transistion' + '.pdf'
# plot with the results of all steps is store under the predefined storpath with the
# earlier defined filename, Michael
analysisplot_obj.postplot.save_fig(storepath, filename)
\ No newline at end of file
......@@ -497,7 +497,7 @@ def plot_output(output_basename, measurements_appendices, show_blocking_plot, co
list_of_frames = []
# storepath is set to working directory with subfolder Plots, Michael
storepath = os.path.join(os.getcwd(),'Plots')
storepath = os.path.join(os.getcwd(),'PostPlots')
# create objet for PostPlot class in PostPlot module, Michael
post_plot = PostPlot.PostPlot(env_cond_sensors = config_data['env_cond_sensors'])
for index, m in enumerate(measurements_appendices):
......
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment