File size: 3,032 Bytes
41c8683 | 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 97 98 99 100 101 102 103 | """
读 evaluate_masks.py 产出的 CSV, 画箱线图.
每个 sample 一个分数 -> 3 个 metric 各画一个箱体, 合并展示.
另外可选: 同时画 3 张独立子图(--mode separate).
用法:
python plot_boxplot.py --csv mask_scores.csv --out_dir plots
python plot_boxplot.py --csv mask_scores.csv --out_dir plots --mode separate
"""
import argparse
import os
import matplotlib.pyplot as plt
import pandas as pd
METRICS = ["dice", "iou", "ms_ssim"]
COLORS = ["#4C72B0", "#55A868", "#C44E52"]
def plot_combined(df, out_dir):
os.makedirs(out_dir, exist_ok=True)
data = [df[m].dropna().values for m in METRICS]
fig, ax = plt.subplots(figsize=(7, 6))
bp = ax.boxplot(
data,
labels=[m.upper() for m in METRICS],
patch_artist=True,
showmeans=True,
meanprops=dict(marker="D", markerfacecolor="white",
markeredgecolor="black", markersize=6),
)
for patch, c in zip(bp["boxes"], COLORS):
patch.set_facecolor(c)
patch.set_alpha(0.6)
ax.set_ylabel("score")
ax.set_title(f"Per-sample metric distribution (n={len(df)})")
ax.grid(axis="y", alpha=0.3)
plt.tight_layout()
out_path = os.path.join(out_dir, "boxplot_combined.png")
plt.savefig(out_path, dpi=150)
plt.close()
print(f"[saved] {out_path}")
def plot_separate(df, out_dir):
os.makedirs(out_dir, exist_ok=True)
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
for ax, m, c in zip(axes, METRICS, COLORS):
vals = df[m].dropna().values
bp = ax.boxplot(
[vals],
labels=[m.upper()],
patch_artist=True,
showmeans=True,
meanprops=dict(marker="D", markerfacecolor="white",
markeredgecolor="black", markersize=6),
)
bp["boxes"][0].set_facecolor(c)
bp["boxes"][0].set_alpha(0.6)
ax.set_title(f"{m.upper()} (n={len(vals)})\nmean={vals.mean():.3f} median={pd.Series(vals).median():.3f}")
ax.grid(axis="y", alpha=0.3)
plt.tight_layout()
out_path = os.path.join(out_dir, "boxplot_separate.png")
plt.savefig(out_path, dpi=150)
plt.close()
print(f"[saved] {out_path}")
def main():
p = argparse.ArgumentParser()
p.add_argument("--csv", required=True)
p.add_argument("--out_dir", default="plots")
p.add_argument("--mode", choices=["combined", "separate", "both"], default="both")
args = p.parse_args()
df = pd.read_csv(args.csv)
df = df[df["status"] == "ok"].copy()
print(f"[info] {len(df)} ok samples")
if args.mode in ("combined", "both"):
plot_combined(df, args.out_dir)
if args.mode in ("separate", "both"):
plot_separate(df, args.out_dir)
if "dataset_fid" in df.columns:
fid = df["dataset_fid"].dropna().unique()
if len(fid):
print(f"[info] dataset FID = {fid[0]}")
if __name__ == "__main__":
main()
"""
python plot_box.py --csv mask_scores.csv --out_dir figs
""" |