"""
[신규 3단계] FinOps 다차원 분석 시각화 엔진 (노드분포 + 일자추이 + 요일패턴 매트릭스 통합)
실행: python step3_analytics.py
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from pathlib import Path
MERGED_DIR = Path("./data/merged")
OUT_PLOT_DIR = Path("./data/output/plots")
OUT_PLOT_DIR.mkdir(parents=True, exist_ok=True)
def init_chart_theme():
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Arial', 'Helvetica', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
sns.set_theme(style="whitegrid")
plt.rcParams['figure.dpi'] = 130
def generate_all_plots():
df = pd.read_parquet(MERGED_DIR / "enriched_fixed_7d.parquet")
df_node = df.groupby("node").agg(
alloc = ("cpu_allocated_core_hours", "sum"),
used = ("cpu_usage_core_hours", "sum")
).reset_index()
df_node["eff_pct"] = (df_node["used"] / df_node["alloc"].clip(lower=0.1) * 100).round(2)
fig, ax = plt.subplots(figsize=(10, 5))
node_range = df_node["eff_pct"].max() - df_node["eff_pct"].min()
if node_range == 0 or np.isnan(node_range):
sns.histplot(data=df_node, x="eff_pct", bins=5, kde=False, color="#1F4E79", ax=ax)
else:
sns.histplot(data=df_node, x="eff_pct", binwidth=5, kde=True, color="#1F4E79", ax=ax)
ax.set_title("Per-Node CPU Efficiency Density Distribution Profiling", weight="bold", pad=15)
ax.set_xlabel("Node Resource Efficiency Score (%)")
fig.savefig(OUT_PLOT_DIR / "chart_n2_node_distribution.png", bbox_inches="tight")
plt.close(fig)
df_trend = df.groupby(["date", "workload_type"])["cpu_waste_core_hours"].sum().unstack().fillna(0)
fig, ax = plt.subplots(figsize=(11, 5.5))
df_trend.plot(kind="bar", stacked=True, ax=ax, cmap="Set3", edgecolor="gray", linewidth=0.4)
ax.set_title("Daily CPU Waste Footprint by Workload Technical Domains", weight="bold", pad=15)
ax.set_ylabel("Total Waste Scale (Core-Hours)")
plt.xticks(rotation=0)
plt.legend(bbox_to_anchor=(1.02, 1), loc="upper left")
fig.savefig(OUT_PLOT_DIR / "chart_t2_daily_waste_stack.png", bbox_inches="tight")
plt.close(fig)
fig, ax = plt.subplots(figsize=(11, 5.5))
sns.heatmap(df_trend, annot=True, fmt=",.1f", cmap="YlOrRd", linewidths=0.5, linecolor="gray", ax=ax, annot_kws={"weight": "bold", "size": 9})
ax.set_title("Infrastructure 2-Dimensional Resource Waste Pattern Matrix", weight="bold", pad=15)
ax.set_xlabel("Observation Dates")
ax.set_ylabel("Workload Domains")
fig.savefig(OUT_PLOT_DIR / "chart_p1_waste_heatmap.png", bbox_inches="tight")
plt.close(fig)
print("✅ [시각화 완료] 3대 마스터 인프라 분석 차트 이미지 저장 완수.")
if __name__ == "__main__":
init_chart_theme()
generate_all_plots()