-
Martin Killenberg authoredMartin Killenberg authored
PostPlot.py 7.49 KiB
import pandas as pd
import sys
from pathlib import Path
import os
from MeasurementPlot import MeasurementPlot
import numpy as np
class PostPlot:
"""
Generate a plot of all data files from the individual measurements to have one plot of the whole
data taking sequence.
Optionally, correlation and regression can be calculated and plotted.
"""
def __init__(self, reference_signal_names, trace_subplot5='', 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 = MeasurementPlot(reference_signal_names, trace_subplot5=trace_subplot5,
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.fig
self.reference_signal_names = reference_signal_names
# read csv-file and import data to data frame
def import_csv(self, csv_file):
data_frame = pd.read_csv(csv_file)
return data_frame
def plot_frame_data(self, data_frame, title, time_unit ='min', measurement_set=None, ):
# set title of plot
self.fig.suptitle("Measurement "+title, color="red")
# reset index of data frame
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.ax1:
element.set_xlabel("Time [%s]" %time_unit)
# make a copy of data_frame in parameter list without changing original during modification
if measurement_set is None:
postplot_data_frame = data_frame.copy()
else:
postplot_data_frame = data_frame.loc[data_frame['SET_NAME'] == measurement_set].copy().reset_index()
# time stamp of index = 0 is the start point of time axis
time_sec = postplot_data_frame.TIMESTAMP - postplot_data_frame.TIMESTAMP[0]
# Set scaling of time axis depending on the time unit given in parameter list.
# Default unit is minutes
time_vals = self.scaling_time_axes(time_sec, time_unit)
# update Timestamps with calculated time values
postplot_data_frame.update(time_vals)
# refresh subplots with data in data frame
self.measplot.draw_in_this_thread(postplot_data_frame, pdf_name='')
# cal PK2PK values of magnitude and phase
PK2PK = self.calc_pkpk_values(postplot_data_frame)
self.edit_annotation_in_plot(annotate_string=PK2PK)
def edit_annotation_in_plot(self, annotate_string='', anno_fontsize=16):
self.measplot.annotation.set_text(annotate_string)
self.measplot.annotation.set_fontsize(anno_fontsize)
def calc_pkpk_values(self, data_frame):
# calc PK2PK values of the two reference signals
delta0 = max(data_frame[self.reference_signal_names[0]]) - min(data_frame[self.reference_signal_names[0]])
delta1 = max(data_frame[self.reference_signal_names[1]]) - min(data_frame[self.reference_signal_names[1]])
# generate text for annotation in first subplot
# FIXME: This used to contain units. We will need some 'pretty printing' values for the nanes
delta_vals_string = ('$\Delta_{PkPk}$'+self.reference_signal_names[0]+': '+str(delta0)+'\n$\Delta_{PkPk}$'+
self.reference_signal_names[1]+': '+str(delta1))
return delta_vals_string
def add_curvefit_to_plot(self, y_lim=None, xvals=[], yvals=[], trace_color='None', trace_label=''):
if y_lim is not None:
# set axis for phase plot to min, max values
self.measplot.ax1[0].set_ylim(y_lim)
self.measplot.path_collection_fit.set_color(trace_color)
self.measplot.path_collection_fit.set_label(trace_label)
# refresh 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 path and file name
def save_fig(self, storepath, filename):
if not os.path.exists(storepath):
os.makedirs(storepath)
self.fig.savefig(os.path.join(storepath, filename))
# scaling time axes depending on the time unit
def scaling_time_axes(self, time_sec, time_unit):
if time_unit == 'min':
time_vals = time_sec/60
elif time_unit == 'hours':
time_vals = time_sec/3600
elif time_unit == 'sec':
time_vals = time_sec
else:
time_vals = time_sec/60
return time_vals
if __name__ == '__main__':
# set result path for post plot
Results_Path = r'TestData_JBY240'
time_unit = 'min'
storepath = os.path.join(Results_Path, 'PostPlots')
# search all csv files in results folder
csv_file_list = list(Path(Results_Path).glob("**/*.csv"))
# selection measurment data should be plotted in subplot5
# 'logger_sens' : values for temperature and humidity of logger sensor in
# measurement instrument chmaber
# 'chamber_sens' : values for temepratere and humidity readback from chamber sensors
# of chamber for measurement instruments
# 'heater_dut_chamber': activity of temp heater and hum heater readback from DUT chamber
# This is also the default parameter
trace_selection = ""
plot_obj = PostPlot(trace_subplot5=trace_selection)
# empty data frame for concat the data frames from csv import to plot full transition
concat_data_frame = pd.DataFrame()
# plot results for each csv-file
for index, csv_file in enumerate(csv_file_list):
data_frame = plot_obj.import_csv(str(csv_file))
title = csv_file.name
# concatenate data frames for plotting full transition data
concat_data_frame = pd.concat([concat_data_frame, data_frame], ignore_index=True, sort=False)
plot_obj.plot_frame_data(data_frame, title, time_unit)
filename = str(csv_file.stem) + '.pdf'
plot_obj.save_fig(storepath, filename)
# plot of all steps of a sweep is plotted in one diagram
plot_obj.plot_frame_data(concat_data_frame, 'Full Transition', time_unit)
filename = 'Full_Transition' + '.pdf'
plot_obj.save_fig(storepath, filename)