plot.py 4.92 KB
Newer Older
jerrrrry's avatar
jerrrrry committed
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
需求:
1. 生成 1 张「跨-Sheet 5 指标汇总」柱状图(保留)  
2. 额外生成 5 张「单指标跨-Sheet 对比柱状图」  
3. 全部输出到指定文件夹
python six_plots.py your.xlsx -o output_folder
"""

import argparse, pandas as pd, matplotlib, os, re
jerrrrry's avatar
jerrrrry committed
12
matplotlib.use('Agg')
jerrrrry's avatar
jerrrrry committed
13
import matplotlib.pyplot as plt
jerrrrry's avatar
jerrrrry committed
14

jerrrrry's avatar
jerrrrry committed
15
# ---------- 工具 ----------
jerrrrry's avatar
jerrrrry committed
16
17
18
19
20
21
22
23
def find_avg_row(df):
    for idx, row in df.iterrows():
        if any(isinstance(cell, str) and re.search(r'平均值|Average', str(cell)) for cell in row):
            return idx
    return df.index[-1]

def extract_values(df):
    idx = find_avg_row(df)
jerrrrry's avatar
jerrrrry committed
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
    vals = [float(v) for v in df.iloc[idx].dropna().iloc[-5:] if str(v).replace('.', '').isdigit()]
    if len(vals) != 5:
        vals = [float(v) for v in df.iloc[-1].dropna().iloc[-5:] if str(v).replace('.', '').isdigit()]
    return dict(zip(['total_throughput', 'generate_throughput', 'singel_road_generate_throughput', 'generate_throughput_without_ttft', 'ttft'], vals))

# ---------- 绘图 ----------
def draw_bar(data, labels, colors, title, out_path, xlabels):
    fig, ax = plt.subplots(figsize=(max(len(xlabels) * 0.8, 12), 6))
    fig.patch.set_facecolor('#ffffff')
    ax.set_facecolor('#ffffff')
    bars = ax.bar(xlabels, data, color=colors, width=0.6)
    for bar, v in zip(bars, data):
        height = bar.get_height()
        ax.annotate(f"{v:.1f}%",
                    xy=(bar.get_x() + bar.get_width() / 2, height),
                    xytext=(0, 3), textcoords='offset points',
                    ha='center', va='bottom', fontsize=7, rotation=60,
                    bbox=dict(boxstyle="round,pad=0.15", facecolor='white', edgecolor='none'))
    ax.set_ylabel("Percentage")
    ax.set_title(title, fontsize=13, weight='bold')
    ax.grid(axis='y', linestyle='-', linewidth=0.25, alpha=0.2)
    ax.tick_params(axis='x', rotation=30)
    plt.tight_layout()
    for ext in ['png', 'pdf']:
        plt.savefig(f"{out_path}.{ext}", dpi=300 if ext == 'png' else None, bbox_inches='tight')
    plt.close()

# ---------- 主流程 ----------
def main():
    parser = argparse.ArgumentParser(description='生成 6 张柱状图:1 张汇总 + 5 张单指标')
    parser.add_argument("xlsx_path", help="输入 Excel 文件")
    parser.add_argument("-o", "--output", default="output", help="输出文件夹")
    args = parser.parse_args()
jerrrrry's avatar
jerrrrry committed
57

jerrrrry's avatar
jerrrrry committed
58
59
60
    xls = pd.ExcelFile(args.xlsx_path)
    summary = {sheet: extract_values(pd.read_excel(xls, sheet_name=sheet, header=None))
               for sheet in xls.sheet_names}
jerrrrry's avatar
jerrrrry committed
61

jerrrrry's avatar
jerrrrry committed
62
    labels = [
jerrrrry's avatar
jerrrrry committed
63
        "total_throughput",
jerrrrry's avatar
jerrrrry committed
64
65
        "generate_throughput",
        "singel_road_generate_throughput",
jerrrrry's avatar
jerrrrry committed
66
67
        "generate_throughput_without_ttft",
        "ttft"
jerrrrry's avatar
jerrrrry committed
68
    ]
jerrrrry's avatar
jerrrrry committed
69
70
    colors = ['#005F73', '#0A9396', '#94D2BD', '#E9D8A6', '#d62728']
    os.makedirs(args.output, exist_ok=True)
jerrrrry's avatar
jerrrrry committed
71

jerrrrry's avatar
jerrrrry committed
72
    # 1. 跨-Sheet 5 指标汇总(原图保持不变)
jerrrrry's avatar
jerrrrry committed
73
74
    models = list(summary.keys())
    x = range(len(models))
jerrrrry's avatar
jerrrrry committed
75
    bar_width = 0.14
jerrrrry's avatar
jerrrrry committed
76
77
78
    fig, ax = plt.subplots(figsize=(max(len(models) * 1.1, 14), 8))
    fig.patch.set_facecolor('#F8F9FA')
    ax.set_facecolor('#FFFFFF')
jerrrrry's avatar
jerrrrry committed
79
80
81
    for i, lab in enumerate(labels):
        vals = [summary[m][lab] for m in models]
        offset = (i - 1.5) * bar_width
jerrrrry's avatar
jerrrrry committed
82
83
        bars = ax.bar([p + offset for p in x], vals, width=bar_width,
                      label=lab.replace('_', ' ').title(), color=colors[i])
jerrrrry's avatar
jerrrrry committed
84
85
        for bar, v in zip(bars, vals):
            height = bar.get_height()
jerrrrry's avatar
jerrrrry committed
86
87
88
89
90
            line_start = (bar.get_x() + bar.get_width() / 2, height)
            text_pos   = (line_start[0], height + max(vals) * 0.05)
            ax.plot([line_start[0], text_pos[0]], [line_start[1], text_pos[1]],
                    color='#555555', linestyle='--', linewidth=0.8, alpha=0.7)
            ax.text(text_pos[0], text_pos[1], f"{v:.1f}%",
jerrrrry's avatar
jerrrrry committed
91
92
                    ha='center', va='bottom', fontsize=7, rotation=60,
                    color='#000000', weight='bold')
jerrrrry's avatar
jerrrrry committed
93
94
95
96
97
98
    ax.set_xticks(x)
    ax.set_xticklabels(models, rotation=25, ha='right', fontsize=10, weight='bold')
    ax.set_ylabel("Percentage", fontsize=12, weight='bold')
    ax.set_title("Throughput Comparison", fontsize=16, weight='bold', pad=20)
    ax.grid(axis='y', linestyle='-', linewidth=0.3, alpha=0.3, color='#DEE2E6')
    ax.legend(frameon=False, loc='upper left', bbox_to_anchor=(1.02, 1), fontsize=9)
jerrrrry's avatar
jerrrrry committed
99
    plt.tight_layout()
jerrrrry's avatar
jerrrrry committed
100
    for ext in ['png', 'pdf']:
jerrrrry's avatar
jerrrrry committed
101
        plt.savefig(os.path.join(args.output, f"summary.{ext}"), dpi=300 if ext == 'png' else None,
jerrrrry's avatar
jerrrrry committed
102
                    bbox_inches='tight')
jerrrrry's avatar
jerrrrry committed
103
    plt.close()
jerrrrry's avatar
jerrrrry committed
104

jerrrrry's avatar
jerrrrry committed
105
106
107
108
109
110
111
    # 2-6. 5 张单指标跨-Sheet 对比图
    for lab, color in zip(labels, colors):
        vals = [summary[s][lab] for s in models]
        draw_bar(vals, [lab], [color],
                 f"{lab.replace('_', ' ').title()} - All Sheets",
                 os.path.join(args.output, lab),
                 models)
jerrrrry's avatar
jerrrrry committed
112

jerrrrry's avatar
jerrrrry committed
113
114
115
116
    print(f"✅ 6 张图已生成:{args.output}")

if __name__ == '__main__':
    main()