Causal-Forcing / scripts /plot_patch_sweep.py
kunyang's picture
Backup repo body (code, configs, workspace) excluding dataset/checkpoints/wan_models
f7e25b2 verified
Raw
History Blame Contribute Delete
2.91 kB
"""Plot the patch-number sweep: 4 small-multiple panels (one metric each, since
they move in opposite directions -> never a dual axis), P on a log2 x-axis with
real P ticks, sweep scatter + quadratic fit, and trained-reference markers
(single-state normalized @P=1, patch @P=8) for cross-check.
"""
import json
import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
J = json.load(open("workspace/markdown/patch_number_sweep.json"))
ps = J["ps"]; sweep = {int(k): v for k, v in J["sweep"].items()}
refs = J["refs"]; fits = J["fits"]
x = np.log2(np.array(ps, float))
# CVD-safe: blue (sweep) + orange (trained refs); recessive gray grid/ink.
BLUE, ORANGE, INK, MUTED, GRID = "#2F6FBF", "#E8710A", "#1c1c1c", "#6b6b6b", "#e6e6e6"
TITLES = {
"clip_text_align": "CLIP text-align (prompt fidelity) ↑",
"clip_temporal": "CLIP temporal coherence ↑",
"flow_smoothness": "Optical-flow smoothness ↑",
"flow_magnitude": "Flow magnitude (dynamic degree)",
}
metrics = J["metrics"]
ref_pt = {"normalized": 1, "patch": 8} # model -> its trained P
fig, axes = plt.subplots(2, 2, figsize=(11, 7.6), dpi=130)
fig.suptitle("Quality vs patch number P — arl2_normalized_patch (P=8 trained ckpt, inference-P swept)\n"
"480p / 21f / seed 0 / 8 prompts · CAVEAT: P=8 in-distribution, other P inference-OOD",
fontsize=11, y=0.99)
for ax, k in zip(axes.flat, metrics):
y = np.array([sweep[p][k] for p in ps])
# quadratic fit in log2(P)
xs = np.array(fits[k]["curve_x_log2P"]); ys = np.array(fits[k]["curve_y"])
ax.plot(xs, ys, "-", color=BLUE, lw=2, alpha=0.55, zorder=1)
ax.scatter(x, y, s=46, color=BLUE, zorder=3, edgecolor="white", linewidth=1.2)
# trained-reference cross-check markers
for m, P in ref_pt.items():
if m in refs and k in refs[m]:
ax.scatter([np.log2(P)], [refs[m][k]], marker="*", s=200, color=ORANGE,
zorder=4, edgecolor="white", linewidth=1.0,
label=f"trained {m} (P={P})")
ax.set_title(TITLES.get(k, k), fontsize=10.5, color=INK, loc="left")
ax.set_xticks(x); ax.set_xticklabels([str(p) for p in ps], fontsize=9)
ax.set_xlabel("patch number P (log₂ spacing)", fontsize=9, color=MUTED)
ax.tick_params(colors=MUTED, labelsize=9)
ax.grid(True, color=GRID, lw=0.8, zorder=0)
for s in ax.spines.values():
s.set_color(GRID)
r = fits[k]["pearson_r_vs_log2P"]
ax.text(0.03, 0.06, f"Pearson r vs log₂P = {r:+.2f}", transform=ax.transAxes,
fontsize=9, color=INK, bbox=dict(boxstyle="round,pad=0.3", fc="white", ec=GRID, alpha=0.85))
if k == "clip_text_align":
ax.legend(loc="upper left", fontsize=8, frameon=False)
fig.tight_layout(rect=[0, 0, 1, 0.95])
out = "workspace/markdown/patch_number_sweep_curve.png"
fig.savefig(out, bbox_inches="tight")
print("wrote", out)