plot.py 3.43 KB
Newer Older
jerrrrry's avatar
jerrrrry committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import argparse, pandas as pd, matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt, re, os

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)
    vals = [float(v) for v in df.iloc[idx].dropna().iloc[-4:] if str(v).replace('.', '').isdigit()]
    if len(vals) != 4:
        vals = [float(v) for v in df.iloc[-1].dropna().iloc[-4:] if str(v).replace('.', '').isdigit()]
    if len(vals) != 4:
        raise ValueError("无法提取4个百分比")
    return {
        "Total_throughput": vals[3],
        "generate_throughput": vals[2],
        "singel_road_generate_throughput": vals[1],
        "generate_throughput_without_ttft": vals[0]
    }

def plot_summary(file_path, output_prefix):
    xls = pd.ExcelFile(file_path)
    summary = {}
    for sheet in xls.sheet_names:
        try:
            df = pd.read_excel(xls, sheet_name=sheet, header=None)
            summary[sheet] = extract_values(df)
        except Exception:
            continue

    if not summary:
        print("❌ 无数据可绘图")
        return

    labels = ["Total_throughput", "generate_throughput", 
              "singel_road_generate_throughput", "generate_throughput_without_ttft"]
    colors = ['#2E5984', '#FF8C42', '#4CB944', '#8C2F39']
    models = list(summary.keys())
    x = range(len(models))
    bar_width = 0.18

    plt.figure(figsize=(max(len(models)*1.2, 12), 8))
    
    # 绘制柱状图
    for i, lab in enumerate(labels):
        vals = [summary[m][lab] for m in models]
        offset = (i - 1.5) * bar_width
        bars = plt.bar([p + offset for p in x], vals, width=bar_width, label=lab, color=colors[i])
        
        # 添加带引导线的标注
        for bar, v in zip(bars, vals):
            height = bar.get_height()
            # 引导线起点(柱顶中心)
            line_start = (bar.get_x() + bar.get_width()/2, height)
            # 文本位置(柱顶上方5%处)
            text_pos = (line_start[0], height + max(vals)*0.05)
            
            # 绘制引导线
            plt.plot([line_start[0], text_pos[0]], [line_start[1], text_pos[1]], 
                    color='gray', linestyle='--', linewidth=0.8, alpha=0.7)
            
            # 添加带背景框的文本
            plt.text(text_pos[0], text_pos[1], f"{v:.1f}%",
                    ha='center', va='bottom',
                    fontsize=6,
                    rotation=60,
                    bbox=dict(facecolor='white', edgecolor='gray', boxstyle='round,pad=0.2'))

    plt.xticks(x, models, rotation=30, ha='right', fontsize=9)
    plt.ylabel("Percentage", fontsize=10)
    plt.title("Throughput Comparison", fontsize=12, pad=20)
    
    # 调整图例
    plt.legend(
        bbox_to_anchor=(1.02, 1),
        loc='upper left',
        fontsize=9,
        frameon=False
    )
    
    plt.subplots_adjust(right=0.8, bottom=0.15)

    for ext in ['png', 'pdf']:
        plt.savefig(f"{output_prefix}.{ext}", dpi=300 if ext == 'png' else None, bbox_inches='tight')
    print(f"✅ 已保存:{output_prefix}.png / .pdf")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("xlsx_path")
    parser.add_argument("-o", "--output", default="summary_chart")
    args = parser.parse_args()
    plot_summary(args.xlsx_path, args.output)