shinka-backup / ccevolve /blog /plot_score_progression.py
JustinTX's picture
Add files using upload-large-folder tool
13d6258 verified
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np
# --- Data ---
phases = [
"Naive ring\narrangement",
"LP + simulated\nannealing",
"Multi-start\noptimization",
"SLSQP joint\noptimization",
"Iterated\nperturbation",
]
scores = [0.96, 2.50, 2.555, 2.619, 2.63598844]
x = np.arange(len(phases))
SOTA = 2.63598308
# --- Style Config (matching blog CSS variables) ---
color_main = "#4a6fa5" # --accent
color_sota = "#c0392b" # warm red
color_text = "#1a1a2e" # --bold-num
color_secondary = "#555" # --text-secondary
color_bg = "#fafaf7" # --bg
color_border = "#e0ddd8" # --border
color_green = "#1a7f37" # blog green for breakthrough
plt.rcParams["font.family"] = "sans-serif"
plt.rcParams["font.sans-serif"] = ["Lato", "Helvetica", "Arial"]
# 更紧凑的画布比例
fig, ax = plt.subplots(figsize=(10, 5.5))
fig.patch.set_facecolor(color_bg)
ax.set_facecolor(color_bg)
# 1. Background & Area
ax.fill_between(x, scores, color=color_main, alpha=0.06, zorder=1)
ax.yaxis.set_major_locator(ticker.MultipleLocator(0.5))
ax.grid(axis="y", color=color_border, linestyle="-", linewidth=0.8, alpha=0.6, zorder=0)
# 2. SOTA Reference
ax.axhline(y=SOTA, color=color_sota, linestyle="--", linewidth=1.2, alpha=0.45, zorder=2)
ax.text(-0.35, SOTA + 0.015, f"PREVIOUS SOTA: {SOTA:.8f}",
fontsize=11, color=color_sota, fontweight="bold", va="bottom")
# 3. The Line
ax.plot(x, scores, color=color_main, linewidth=3.5, zorder=3, alpha=0.85)
# 4. Points & Score Labels
for i, score in enumerate(scores):
is_breakthrough = score > SOTA
is_last = (i == len(scores) - 1)
m_color = color_green if is_breakthrough else color_main
ax.scatter(x[i], score, color=m_color, s=280, zorder=4, alpha=0.12)
ax.scatter(x[i], score, color=m_color, s=90, zorder=5, edgecolors=color_bg, linewidths=1.5)
label = f"{score:.8f}" if is_last else f"{score:.3f}"
y_offset = 0.06 if is_last else 0.05
ax.text(x[i], score + y_offset, label, ha="center", va="bottom",
fontsize=14 if not is_last else 16,
fontweight="bold", color=m_color, zorder=6)
# 5. Staggered Annotations
box_style_default = dict(boxstyle="round,pad=0.4", fc=color_bg, ec=color_border, alpha=0.95)
box_style_highlight = dict(boxstyle="round,pad=0.4", fc="#dafbe1", ec=color_green, alpha=1)
# 三个注释框都放在曲线下方,y 位置逐渐升高避免重叠
ax.annotate(
"Agent reads ArXiv paper,\nswitches to LP formulation",
xy=(x[1], scores[1]), xytext=(x[1], 1.35),
fontsize=13, color=color_secondary, ha="center",
arrowprops=dict(arrowstyle="->", color="#999", lw=1.2, connectionstyle="arc3,rad=0.1"),
bbox=box_style_default, zorder=7
)
ax.annotate(
"SLSQP breakthrough:\njoint radius + position opt.",
xy=(x[3], scores[3]), xytext=(x[3], 1.65),
fontsize=13, color=color_secondary, ha="center",
arrowprops=dict(arrowstyle="->", color="#999", lw=1.2, connectionstyle="arc3,rad=0.1"),
bbox=box_style_default, zorder=7
)
ax.annotate(
"Parallel perturbation\nchains surpass SOTA",
xy=(x[4], scores[4]), xytext=(x[4], 1.95),
fontsize=13, color=color_green, ha="center", fontweight="bold",
arrowprops=dict(arrowstyle="->", color=color_green, lw=1.5, connectionstyle="arc3,rad=0.1"),
bbox=box_style_highlight, zorder=7
)
# --- Final Layout ---
ax.set_xticks(x)
ax.set_xticklabels(phases, fontsize=13, color=color_secondary, fontweight="medium")
ax.set_ylabel("Score (Sum of Radii)", fontsize=13, color=color_secondary, labelpad=10)
ax.set_title("Circle Packing Score Progression (26 circles in unit square)",
fontsize=19, fontweight="bold", color=color_text, pad=16)
for spine in ["top", "right", "left"]:
ax.spines[spine].set_visible(False)
ax.spines["bottom"].set_color(color_border)
# 收紧 Y 轴范围,减少空白
ax.set_ylim(0.75, 2.95)
ax.set_xlim(-0.4, len(phases) - 0.2)
plt.tight_layout()
# Save high-res to publish directory
output_path = "/home/tengxiao/pj/ShinkaEvolve/ccevolve/blog/publish/score_progression.png"
plt.savefig(output_path, dpi=300, bbox_inches="tight", facecolor=color_bg)
print(f"Saved to {output_path}")
plt.show()