Newer
Older
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import time
# Different exceptions can be thrown while plotting, depending on the backend.
# We catch them all locally and raise our own exception instead
class PlottingError(Exception):
"Raised when plotting fails"
pass
def __init__(self, title='', legend_sensor0 = ['Temperature Sensor0', 'Humidity Sensor0'], \
legend_sensor1 =['Temperature Sensor1','Humidity Sensor1', 'Air Pressure Sensor1']):
# set python for opening an separate plot window when starting from anaconda, Michael
if 'ipykernel' in sys.modules:
from IPython import get_ipython
get_ipython().run_line_magic('matplotlib', 'qt')
# set contents of labels for additional external sensors in legend of subplots, Michael
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]
# Third, Fourth and Fifth plot for additional external sensors, Michael
self.fig, self.ax1 = plt.subplots(5, figsize=(25, 20))
self.fig.subplots_adjust(bottom= 0.1, hspace = 0.4)
self.fig.suptitle("Measurement "+title, color="red")
# First plot: Phase and magnitude, Michael
self.path_collection_phase = self.ax1[0].scatter([], [], c='red', marker='<', label='DUT Phase')
self.magnitude_axis = self.ax1[0].twinx()
# in entry of legend for phase and magnitude the word DUT is added in front, Michael
self.path_collection_mag = self.magnitude_axis.scatter([], [], c='#3120E0', marker='4', label='DUT Magnitude')
self.equi_axis0 = self.ax1[0].twinx()
self.equi_axis0.spines['right'].set_position(('outward', 75))
self.path_collection_equi0 = self.equi_axis0.scatter([], [], c='black', marker=".", label='Equilibrium_Indicator')
# units added to y-axes of subplot 1, Michael
self.ax1[0].set_xlabel("TIMESTAMP")
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')
# fix range to 0..31 with some extra margin for plotting
self.equi_axis0.set_ylim(-1, 32)
self.ax1[0].grid(True, linestyle=":")
all_path_collections = [self.path_collection_phase, self.path_collection_mag, self.path_collection_equi0]
labels = [pc.get_label() for pc in all_path_collections]
self.ax1[0].legend(all_path_collections, labels, loc='lower right')
# Second plot: Humidity and temperature of climate chamber requested from internal sensors of chamber
self.path_collection_temp = self.ax1[1].scatter([], [], c='blue', marker='p', label="Chamber Temperature")
self.humidity_axis = self.ax1[1].twinx()
self.path_collection_hum = self.humidity_axis.scatter([], [], c='green', marker="*", label="Chamber Humidity")
self.equi_axis1 = self.ax1[1].twinx()
self.equi_axis1.spines['right'].set_position(('outward', 75))
self.path_collection_equi1 = self.equi_axis1.scatter([], [], c='black', marker=".", label="Equilibrium_Indicator")
# units added to y-axes of subplot 2, Michael
self.ax1[1].set_xlabel("TIMESTAMP")
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 is changed to Indiccator Value because it's shorter, Michael
self.equi_axis1.set_ylabel("INDICATOR VALUE", color='black')
self.equi_axis1.set_ylim(-1, 32)
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]
self.ax1[1].legend(all_path_collections, labels, loc='lower right')
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# Third plot: temperature 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
self.path_collection_temp_sensor0 = self.ax1[2].scatter([],[], c='red', marker='p', label=label_temp_sensor0)
self.ext_sens_hum_axis = self.ax1[2].twinx()
self.path_collection_hum_sensor0 = self.ext_sens_hum_axis.scatter([],[], c='purple', marker='*', label=label_hum_sensor0)
self.ax1[2].set_xlabel("TIMESTAMP")
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]
self.ax1[2].legend(all_path_collections, labels, loc='lower right')
# Forth plot: temperatur external sensor1, humidity external sensors1, air pressure external sensor 1, 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 sensor 0 can be configure by ext_sens_data.json, Michael
self.path_collection_temp_sensor1 = self.ax1[3].scatter([],[], c='green', marker='*', label=label_temp_sensor1)
self.sec_ext_hum_sens_axis = self.ax1[3].twinx()
self.path_collection_hum_sensor1 = self.sec_ext_hum_sens_axis.scatter([],[], c='orange', marker='>', label=label_hum_sensor1)
self.press_axis = self.ax1[3].twinx()
self.press_axis.spines['right'].set_position(('outward', 75))
self.path_collection_press = self.press_axis.scatter([],[], c='grey', marker='4', label=label_air_press_sensor1)
self.ax1[3].set_xlabel("TIMESTAMP")
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]
self.ax1[3].legend(all_path_collections, labels, loc='lower right')
# 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([],[], c='black', marker='<', label='Temp Heater')
self.path_collection_hum_heater = self.ax1[4].scatter([],[], c='brown', marker='o', label='Hum Heater')
self.ax1[4].set_xlabel("TIMESTAMP")
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]
self.ax1[4].legend(all_path_collections, labels, loc='lower right')
def draw(self, data_frame, pdf_name=''):
timestamps = data_frame.TIMESTAMP
minimum, maximum = self.get_extended_min_max(timestamps)
self.ax1[0].set_xlim(minimum, maximum)
self.ax1[1].set_xlim(minimum, maximum)
# because subplots where increase x-axis limits has to be set equal to first and second plot, Michael
self.ax1[2].set_xlim(minimum, maximum)
self.ax1[3].set_xlim(minimum, maximum)
self.ax1[4].set_xlim(minimum, maximum)
# refresh data for phase in subplot for phase and magnitude
phases = data_frame.S21_PHASE
minimum, maximum = self.get_extended_min_max(phases)
self.ax1[0].set_ylim(minimum, maximum)
self.path_collection_phase.set_offsets(np.c_[timestamps, phases])
# refresh data for magnitude in subplot for phase and magnitude
magnitudes = data_frame.S21_MAGNITUDE
minimum, maximum = self.get_extended_min_max(magnitudes)
self.magnitude_axis.set_ylim(minimum, maximum)
self.path_collection_mag.set_offsets(np.c_[timestamps, magnitudes])
# refresh data for chamber temperature in subplot for chamber temperature and humidity
temperatures = data_frame.READBACK_TEMPERATURE
minimum, maximum = self.get_extended_min_max(temperatures)
self.ax1[1].set_ylim(minimum, maximum)
self.path_collection_temp.set_offsets(np.c_[timestamps, temperatures])
# refresh data for chamber humidity in subplot for chamber temperature and humidity
humidities = data_frame.READBACK_HUMIDITY
minimum, maximum = self.get_extended_min_max(humidities)
self.humidity_axis.set_ylim(minimum, maximum)
self.path_collection_hum.set_offsets(np.c_[timestamps, humidities])
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# refresh temperatures for external sensors in subplots for sensor 0 and sensor1, Michael
temp_sensor0 = data_frame.TEMP_SENSOR0
temp_sensor1 = data_frame.TEMP_SENSOR1
minimum, maximum = self.get_extended_min_max(temp_sensor0)
self.ax1[2].set_ylim(minimum, maximum)
minimum, maximum = self.get_extended_min_max(temp_sensor1)
self.ax1[3].set_ylim(minimum, maximum)
self.path_collection_temp_sensor0.set_offsets(np.c_[timestamps, temp_sensor0])
self.path_collection_temp_sensor1.set_offsets(np.c_[timestamps, temp_sensor1])
# refresh humidities external sensors in subplots for sensor 0 and sensor 1, Michael
hum_sensor0 = data_frame.HUM_SENSOR0
hum_sensor1 = data_frame.HUM_SENSOR1
minimum, maximum = self.get_extended_min_max(hum_sensor0)
self.ext_sens_hum_axis.set_ylim(minimum, maximum)
minimum, maximum = self.get_extended_min_max(hum_sensor1)
self.sec_ext_hum_sens_axis.set_ylim(minimum, maximum)
self.path_collection_hum_sensor0.set_offsets(np.c_[timestamps, hum_sensor0])
self.path_collection_hum_sensor1.set_offsets(np.c_[timestamps, hum_sensor1])
# refresh air pressure of external sensor in subplot for sensor 1 Michael
air_press = data_frame.AIR_PRESSURE
minimum, maximum = self.get_extended_min_max(air_press)
self.press_axis.set_ylim(minimum, maximum)
self.path_collection_press.set_offsets(np.c_[timestamps, air_press])
# refresh heater percentage values of climate chamber in subplot of heater values, Michael
temp_heater = data_frame.TEMP_HEATER
hum_heater = data_frame.HUM_HEATER
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)
self.ax1[4].set_ylim(minimum-0.05*(maximum-minimum), maximum+0.05*(maximum-minimum))
self.path_collection_temp_heater.set_offsets(np.c_[timestamps, temp_heater])
self.path_collection_hum_heater.set_offsets(np.c_[timestamps, hum_heater])
self.path_collection_equi0.set_offsets(np.c_[timestamps, data_frame.EQUILIBRIUM_INDICATOR])
self.path_collection_equi1.set_offsets(np.c_[timestamps, data_frame.EQUILIBRIUM_INDICATOR])
if not pdf_name == '':
self.fig.savefig(pdf_name)
plt.show()
if plt.isinteractive():
try:
self.fig.canvas.draw()
self.fig.canvas.flush_events()
except Exception as e:
raise PlottingError from e
# 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.:
return array.min()-0.05*distance, array.max()+0.05*distance
# test procedure for measurement plot procedure
if __name__ == '__main__':
m = MeasurementPlot()
plt.ion()
measurements = []
for i in range(20):
measurement = {
'TIMESTAMP': i,
'READBACK_TEMPERATURE': 25 - i,
'READBACK_HUMIDITY': 10 + 0.1*i,
'EQUILIBRIUM_INDICATOR': i % 4,
'S21_PHASE': 20 - 2*i,
'S21_MAGNITUDE': 0.3*i,
'TEMP_HEATER': 10,
# percentage humidity heater, Michael
'HUM_HEATER': 3,
# Temperature Sensor0of external temp sensor added, Michael
'TEMP_SENSOR0': i,
# Temperature Sensor 1 of external temp sensor added, Michael
'TEMP_SENSOR1': 25-i,
# Humidity Sensor0 of external hum sensor added, Michael
'HUM_SENSOR0': 40,
# Humidity Sensor 1 of external hum sensor added, Michael
'HUM_SENSOR1': 45,
# Air pressure of external sensor added, Michael
'AIR_PRESSURE': 1200-10*i
}
measurements.append(measurement)
data_frame = pd.DataFrame(measurements)
# plot of data frame with test data for actual step
m.draw(data_frame)
print(str(i))
time.sleep(0.3)
print('I am done. ')
plt.ioff()
m.draw(data_frame, 'the.pdf')