Modify plotting code to handle headerless csv
All checks were successful
Generate Power Graph / plot (push) Successful in 1m58s
All checks were successful
Generate Power Graph / plot (push) Successful in 1m58s
This commit is contained in:
parent
974d23a7d4
commit
086e415ad9
2 changed files with 73 additions and 72 deletions
|
|
@ -1,34 +1,39 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
plot_power.py
|
||||
Forgejo CI: visualize AMD TUF APU/GPU telemetry as a clear bar graph.
|
||||
Forgejo CI: visualize AMD TUF APU/GPU telemetry as a clean bar graph.
|
||||
Compatible with headerless CSV output from amd-monitor.sh
|
||||
Author: MarkMental
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
from datetime import datetime
|
||||
|
||||
CSV_PATH = "power_log.csv"
|
||||
OUTPUT_FILE = "power_graph.png"
|
||||
|
||||
print(f"📊 Reading {CSV_PATH}...")
|
||||
df = pd.read_csv(CSV_PATH)
|
||||
|
||||
# --- Normalize timestamp ---
|
||||
# --- Load CSV without headers ---
|
||||
df = pd.read_csv(
|
||||
CSV_PATH,
|
||||
names=["timestamp", "apu_w", "gpu_w", "total_w", "apu_temp", "gpu_temp"],
|
||||
comment="#",
|
||||
)
|
||||
|
||||
# --- Convert timestamps ---
|
||||
df["timestamp"] = pd.to_datetime(df["timestamp"], errors="coerce")
|
||||
df["time_fmt"] = df["timestamp"].dt.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# --- Downsample if extremely long (avoid thousands of bars) ---
|
||||
# --- Downsample if too many entries ---
|
||||
if len(df) > 200:
|
||||
df = df.iloc[::max(1, len(df)//200), :]
|
||||
|
||||
# --- Plot setup ---
|
||||
# --- Plot ---
|
||||
fig, ax1 = plt.subplots(figsize=(12, 6))
|
||||
|
||||
# Power bars
|
||||
width = 0.3
|
||||
x = range(len(df))
|
||||
width = 0.3
|
||||
|
||||
ax1.bar([i - width for i in x], df["apu_w"], width, label="APU Power (W)", color="#ff9933")
|
||||
ax1.bar(x, df["gpu_w"], width, label="GPU Power (W)", color="#66cc66")
|
||||
ax1.bar([i + width for i in x], df["total_w"], width, label="Total Power (W)", color="#3399ff")
|
||||
|
|
@ -39,25 +44,21 @@ ax1.set_title("AMD TUF Power & Temperature Log")
|
|||
ax1.set_xticks(x[::max(1, len(x)//10)])
|
||||
ax1.set_xticklabels(df["time_fmt"].iloc[::max(1, len(x)//10)], rotation=45, ha="right")
|
||||
|
||||
# --- Secondary axis for temperature ---
|
||||
if "apu_temp" in df.columns and "gpu_temp" in df.columns:
|
||||
ax2 = ax1.twinx()
|
||||
ax2.plot(x, df["apu_temp"], "--", color="red", linewidth=1.2, label="APU Temp (°C)")
|
||||
ax2.plot(x, df["gpu_temp"], "--", color="purple", linewidth=1.2, label="GPU Temp (°C)")
|
||||
ax2.set_ylabel("Temperature (°C)")
|
||||
ax2.set_ylim(min(df[["apu_temp","gpu_temp"]].min())-5,
|
||||
max(df[["apu_temp","gpu_temp"]].max())+5)
|
||||
# --- Secondary axis for temperatures ---
|
||||
ax2 = ax1.twinx()
|
||||
ax2.plot(x, df["apu_temp"], "--", color="red", linewidth=1.2, label="APU Temp (°C)")
|
||||
ax2.plot(x, df["gpu_temp"], "--", color="purple", linewidth=1.2, label="GPU Temp (°C)")
|
||||
ax2.set_ylabel("Temperature (°C)")
|
||||
ax2.set_ylim(min(df[["apu_temp","gpu_temp"]].min())-5,
|
||||
max(df[["apu_temp","gpu_temp"]].max())+5)
|
||||
|
||||
# Combine legends
|
||||
lines1, labels1 = ax1.get_legend_handles_labels()
|
||||
lines2, labels2 = ax2.get_legend_handles_labels()
|
||||
ax1.legend(lines1 + lines2, labels1 + labels2, loc="upper left")
|
||||
else:
|
||||
ax1.legend(loc="upper left")
|
||||
# --- Combined legend ---
|
||||
lines1, labels1 = ax1.get_legend_handles_labels()
|
||||
lines2, labels2 = ax2.get_legend_handles_labels()
|
||||
ax1.legend(lines1 + lines2, labels1 + labels2, loc="upper left")
|
||||
|
||||
plt.grid(axis="y", alpha=0.3)
|
||||
plt.tight_layout()
|
||||
plt.savefig(OUTPUT_FILE, dpi=150)
|
||||
print(f"✅ Saved clean bar graph: {OUTPUT_FILE}")
|
||||
|
||||
print(f"✅ Saved graph: {OUTPUT_FILE}")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue