plot.py 4.99 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
    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()]
jerrrrry's avatar
jerrrrry committed
27
28
29
30
31
32
33
    return {
        "total_throughput": vals[4],
        "generate_throughput": vals[3],
        "singel_road_generate_throughput": vals[1],
        "generate_throughput_without_ttft": vals[0],
        "ttft": vals[2]
    }
jerrrrry's avatar
jerrrrry committed
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

# ---------- 绘图 ----------
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
63

jerrrrry's avatar
jerrrrry committed
64
65
66
    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
67

jerrrrry's avatar
jerrrrry committed
68
    labels = [
jerrrrry's avatar
jerrrrry committed
69
        "total_throughput",
jerrrrry's avatar
jerrrrry committed
70
71
        "generate_throughput",
        "singel_road_generate_throughput",
jerrrrry's avatar
jerrrrry committed
72
73
        "generate_throughput_without_ttft",
        "ttft"
jerrrrry's avatar
jerrrrry committed
74
    ]
jerrrrry's avatar
jerrrrry committed
75
76
    colors = ['#005F73', '#0A9396', '#94D2BD', '#E9D8A6', '#d62728']
    os.makedirs(args.output, exist_ok=True)
jerrrrry's avatar
jerrrrry committed
77

jerrrrry's avatar
jerrrrry committed
78
    # 1. 跨-Sheet 5 指标汇总(原图保持不变)
jerrrrry's avatar
jerrrrry committed
79
80
    models = list(summary.keys())
    x = range(len(models))
jerrrrry's avatar
jerrrrry committed
81
    bar_width = 0.14
jerrrrry's avatar
jerrrrry committed
82
83
84
    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
85
86
87
    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
88
89
        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
90
91
        for bar, v in zip(bars, vals):
            height = bar.get_height()
jerrrrry's avatar
jerrrrry committed
92
93
94
95
96
            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
97
98
                    ha='center', va='bottom', fontsize=7, rotation=60,
                    color='#000000', weight='bold')
jerrrrry's avatar
jerrrrry committed
99
100
101
102
103
104
    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
105
    plt.tight_layout()
jerrrrry's avatar
jerrrrry committed
106
    for ext in ['png', 'pdf']:
jerrrrry's avatar
jerrrrry committed
107
        plt.savefig(os.path.join(args.output, f"summary.{ext}"), dpi=300 if ext == 'png' else None,
jerrrrry's avatar
jerrrrry committed
108
                    bbox_inches='tight')
jerrrrry's avatar
jerrrrry committed
109
    plt.close()
jerrrrry's avatar
jerrrrry committed
110

jerrrrry's avatar
jerrrrry committed
111
112
113
114
115
116
117
    # 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
118

jerrrrry's avatar
jerrrrry committed
119
120
121
122
    print(f"✅ 6 张图已生成:{args.output}")

if __name__ == '__main__':
    main()