- 新增 3.5 成本效益量化分析与表 5 结论-证据映射表(8 条结论可核验) - 结论 5.2 为五类受众补充执行周期、量化目标与证据关联 - 创建 notebooks/pilot_analysis.md(26 项数据一致性核验通过) - 创建 plots/ 三张图表 + CSV 数据 + 生成脚本 - 创建 processing/validate_data.py(27 项校验通过) - 更新 data/paper_loop/round_notes.md 与 sync_summary.md
93 lines
2.9 KiB
Python
93 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
||
"""生成试点数据分析图表。
|
||
|
||
输出:
|
||
plots/pilot_run_data.png — 各地市预警数据柱状图
|
||
plots/vendor_effort.png — 供应商人天投入饼图
|
||
plots/access_cost.png — 接入链路耗时对比图
|
||
"""
|
||
|
||
import csv
|
||
import os
|
||
import sys
|
||
|
||
import matplotlib
|
||
matplotlib.use("Agg")
|
||
import matplotlib.pyplot as plt
|
||
|
||
PLOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
|
||
|
||
def load_csv(name):
|
||
path = os.path.join(PLOT_DIR, name)
|
||
with open(path, encoding="utf-8") as f:
|
||
return list(csv.DictReader(f))
|
||
|
||
|
||
def plot_run_data():
|
||
rows = load_csv("pilot_run_data.csv")
|
||
cities = [r["city"] for r in rows]
|
||
alerts = [int(r["alert_count"]) if r["alert_count"] else 0 for r in rows]
|
||
colors = ["#2196F3" if a > 0 else "#BDBDBD" for a in alerts]
|
||
|
||
fig, ax = plt.subplots(figsize=(10, 5))
|
||
bars = ax.bar(cities, alerts, color=colors)
|
||
ax.set_ylabel("累计预警数据(条)")
|
||
ax.set_title("各地市电量突增能力应用预警数据(截至 2026-06-25)")
|
||
for bar, val in zip(bars, alerts):
|
||
if val > 0:
|
||
ax.text(bar.get_x() + bar.get_width() / 2, val + 200,
|
||
f"{val:,}", ha="center", fontsize=9)
|
||
plt.xticks(rotation=30, ha="right")
|
||
plt.tight_layout()
|
||
plt.savefig(os.path.join(PLOT_DIR, "pilot_run_data.png"), dpi=150)
|
||
plt.close()
|
||
|
||
|
||
def plot_vendor_effort():
|
||
rows = load_csv("vendor_effort.csv")
|
||
labels = [r["category"] for r in rows]
|
||
sizes = [int(r["person_days"]) for r in rows]
|
||
|
||
fig, ax = plt.subplots(figsize=(8, 6))
|
||
wedges, texts, autotexts = ax.pie(
|
||
sizes, labels=labels, autopct="%1.0f%%", startangle=140,
|
||
textprops={"fontsize": 9},
|
||
)
|
||
ax.set_title("供应商人天投入结构(合计 100 人天)")
|
||
plt.tight_layout()
|
||
plt.savefig(os.path.join(PLOT_DIR, "vendor_effort.png"), dpi=150)
|
||
plt.close()
|
||
|
||
|
||
def plot_access_cost():
|
||
rows = load_csv("access_cost.csv")
|
||
steps = [r["step"] for r in rows if r["step"] != "端到端合计"]
|
||
ideal = [int(r["ideal_days"]) for r in rows if r["step"] != "端到端合计"]
|
||
actual = [int(r["actual_days"]) for r in rows if r["step"] != "端到端合计"]
|
||
|
||
x = range(len(steps))
|
||
width = 0.35
|
||
fig, ax = plt.subplots(figsize=(10, 5))
|
||
ax.bar([i - width / 2 for i in x], ideal, width, label="理想耗时", color="#4CAF50")
|
||
ax.bar([i + width / 2 for i in x], actual, width, label="实际耗时", color="#FF5722")
|
||
ax.set_ylabel("耗时(工作日)")
|
||
ax.set_title("单地市接入链路耗时:理想 vs 实际")
|
||
ax.set_xticks(x)
|
||
ax.set_xticklabels(steps, rotation=20, ha="right")
|
||
ax.legend()
|
||
plt.tight_layout()
|
||
plt.savefig(os.path.join(PLOT_DIR, "access_cost.png"), dpi=150)
|
||
plt.close()
|
||
|
||
|
||
def main():
|
||
plot_run_data()
|
||
plot_vendor_effort()
|
||
plot_access_cost()
|
||
print("图表已生成:pilot_run_data.png, vendor_effort.png, access_cost.png")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|