diff --git a/results-loop/fig_phase.png b/results-loop/fig_phase.png index 8415156..0c2ae40 100644 Binary files a/results-loop/fig_phase.png and b/results-loop/fig_phase.png differ diff --git a/scripts/fig_phase.py b/scripts/fig_phase.py index aee878f..56bc9c0 100644 --- a/scripts/fig_phase.py +++ b/scripts/fig_phase.py @@ -16,11 +16,13 @@ OUT = Path(__file__).resolve().parent.parent / "results-loop" # name rho easy hard color # name rho(plot x) easy hard color dy PTS = [ - ("untrained α-merge\n(training-free)", 0.38, 0.885, 0.143, "#8a8f98", 16), - ("trained merge\n(anchored B, curriculum)", 0.29, 0.885, 0.464, "#2b6cb0", -60), + ("untrained α-merge\n(training-free)\nhard 14%", 0.40, 0.885, 0.143, "#8a8f98", -52), + ("trained merge\n(anchored B, curriculum)", 0.26, 0.885, 0.464, "#2b6cb0", -60), + ("per-depth merges\n(time-varying, anchored)\nhard 36% (depth-stranded)", 0.325, 0.893, 0.357, "#805ad5", 18), ("Parcae rec\n(ρ<1 enforced, learned B)", 0.292, 0.713, 0.429, "#2f855a", -58), ("unconstrained rec\n(learned A,B)", 4.5, 0.697, 0.393, "#c53030", 16), ] +# x jittered around true rho=0.3 for the three anchored arms (visibility) # untrained merge x offset for visibility (true rho = 0.30) fig, ax = plt.subplots(figsize=(7.6, 5.2)) @@ -36,15 +38,18 @@ ax.text(3.1, 0.615, "norm projection converts\nexplosion → stationary churn\n" for name, rho, easy, hard, c, dy in PTS: ax.scatter(rho, easy, s=90 + 900 * hard, color=c, alpha=0.85, zorder=3, edgecolor="white", linewidth=1.5) - ax.annotate(f"{name}\nhard {hard:.0%}", - (rho, easy), textcoords="offset points", xytext=(0, dy), + lbl = name if ("stranded" in name or "14%" in name) else f"{name}\nhard {hard:.0%}" + dx = 62 if "14%" in name else 0 + ax.annotate(lbl, + (rho, easy), textcoords="offset points", xytext=(dx, dy), ha="center", fontsize=8.5, color=c) ax.annotate("", xy=(0.278, 0.735), xytext=(0.288, 0.862), arrowprops=dict(arrowstyle="->", color="#2f855a", lw=1.3)) -ax.text(0.42, 0.79, "learned B + no curriculum:\nfixed point leaves the\n" +ax.text(0.46, 0.775, "learned B + no curriculum:\nfixed point leaves the\n" "substrate manifold", fontsize=8, color="#2f855a", ha="left") + ax.set_xlim(0.2, 12) ax.set_ylim(0.58, 1.0) ax.set_xlabel("ρ(A) — spectral radius of the trained state map (dynamics dial)")