-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvis.py
More file actions
104 lines (88 loc) · 4.23 KB
/
Copy pathvis.py
File metadata and controls
104 lines (88 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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
import matplotlib.pyplot as plt
import pandas as pd
from datetime import datetime
data = []
chamber = "Input2" # The name of the chamber output that is being plotted against the standard
date_marker = "DATE"
# Read the file (can change this)
with open("metcal - Copy (7).out", "r") as file:
lines = file.readlines()
# Parse the lines and assemble the dataframe
# Each sensor gets its own line
for line in lines:
parts = line.strip().split()
# Update the date if a new DATE line is found (should only be header)
if line.startswith("DATE"):
date_part = parts[1]
# Detect time updates and assemble timestamp, allow it to break here
if line.startswith("TIME") and date_part is not None:
time_part = parts[1]
current_timestamp = datetime.strptime(
f"{date_part} {time_part}", "%d-%b-%Y %H:%M:%S"
)
# Detect sensor data (excluding headers and metadata)
# Always seems to be 9 entries, sensor lines start with TP of some variety
elif len(parts) == 9 and parts[0].startswith("TP"):
sensor_id = parts[0]
rawd = float(parts[1])
value = float(parts[3])
serial = parts[-1] # Use Serial number instead of "TP1M"
data.append([current_timestamp, sensor_id, rawd, value, serial])
# Convert to DataFrame
df = pd.DataFrame(data, columns=["Timestamp", "Sensor", "Rawd", "Value", "Serial"])
df["Timestamp"] = pd.to_datetime(df["Timestamp"])
sensors = df["Serial"].unique() # For later in visualizing
# Handle the setpoints (setting, time HH:MM)
setpoints_df = pd.read_csv("setpoints.csv", dtype={"sp": float, "time": str})
if date_marker.lower() in str(list(setpoints_df.columns)).lower(): # If there is a date column, don't use `date_part`
setpoints_df["Datetime"] = pd.to_datetime(
setpoints_df["DATE"] + " " + setpoints_df["time"],
format="%m/%d/%y %H:%M")
else:
setpoints_df["Datetime"] = setpoints_df["time"].apply(lambda x: datetime.strptime(f"{date_part} {x}:00", "%d-%b-%Y %H:%M:%S"))
# Handle the observations (TT Input2 (humidity), time HH:MM)
obs_df = pd.read_csv("obs.csv", dtype={chamber: float, "time": str})
if date_marker.lower() in str(list(obs_df.columns)).lower():
obs_df["Datetime"] = pd.to_datetime(
obs_df["DATE"] + " " + setpoints_df["time"],
format="%m/%d/%y %H:%M")
else:
obs_df["Datetime"] = obs_df["time"].apply(lambda x: datetime.strptime(f"{date_part} {x}:00", "%d-%b-%Y %H:%M:%S"))
# Figure setup
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(12, 8), sharex=True)
# Plot Rawd (raw output) on the first subplot
for sensor in sensors:
subset = df[df["Serial"] == sensor]
axes[0].plot(
subset["Timestamp"], subset["Rawd"], label=f"{sensor}", linestyle="--")
axes[0].set_ylabel("Rawd Readings")
axes[0].set_title("Sensor Rawd Readings Over Time", pad=20)
axes[0].legend()
axes[0].grid()
# Plot Value (transformed with current coefs) on the second subplot
for sensor in sensors:
subset = df[df["Serial"] == sensor]
axes[1].plot(subset["Timestamp"], subset["Value"], label=f"{sensor}")
axes[1].scatter(obs_df["Datetime"], obs_df[chamber], label="Observed chamber value", color="red", marker="x")
if "Omni" in obs_df.columns():
axes[1].scatter(obs_df["Datetime"], obs_df["Omni"], label="Omniport reading", color="black", marker="+")
axes[1].set_ylabel("Value Readings")
axes[1].set_title("Sensor Value Readings Over Time", pad=20)
axes[1].set_xlabel("Timestamp")
axes[1].legend()
axes[1].grid()
# Add vertical lines for the setpoints
for idx, row in setpoints_df.iterrows():
setpoint_time = row["Datetime"]
sp_value = row["sp"]
# Draw the vertical line at the setpoint time
axes[0].axvline(setpoint_time, color="grey", linestyle="-", linewidth=2)
axes[1].axvline(setpoint_time, color="grey", linestyle="-", linewidth=2)
# Add label for the setpoint value at the top of the figure
axes[0].text(setpoint_time, max(df["Rawd"]) * 1.05, f"{sp_value}", ha="center", va="bottom", color="black", fontsize=10)
axes[1].text(setpoint_time, max(df["Value"]) * 1.05, f"{sp_value}", ha="center", va="bottom", color="black", fontsize=10)
plt.xticks(rotation=45)
plt.tight_layout()
# Save the figure
plt.savefig("sensor_data_subplots.png", dpi=300, bbox_inches="tight")
plt.close()