Skip to content

Commit 5a7f657

Browse files
jeremymanningclaude
andcommitted
Weights animation: sliding-window style in a fixed space
Switch back from animate='spin' to the classic animate=True sliding window, per review. The critical property -- the space inside the cube is fixed for the whole animation, independent of which window is visible -- is guaranteed by the pipeline (helpers.scale normalizes once from the full stacked dataset and the window updater never touches axis limits) and verified programmatically: axis limits are identical across frames while the visible fragment's extent slides along the loop. (The earlier claim that window mode showed a static tangle was a frame- extraction bug in the verification harness -- PIL's ImageSequence yields one re-seeked image object, so materializing it with list() produced N copies of the final frame. Measured correctly, the window render rotates and the comet travels: mean inter-second frame motion 8.3, 0 clipped frames.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent b362d67 commit 5a7f657

3 files changed

Lines changed: 8 additions & 5 deletions

File tree

-3.16 MB
Loading

notes/session_2026-07-01_dev-2.0_kickoff.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ Other round-4.5 fixes: repeated-hyperalign scale collapse (procrustes optimal sc
150150

151151
## Round 4.5 SHIPPED (2317cd5), then weights loop-shape correction (2026-07-02 late)
152152
- WEIGHTS FINAL recipe (scripts/generate_weights_trajectory.py): smooth(gaussian var=300, scipy gaussian_filter1d sigma=sqrt(300)) -> align('SRM', n_iter=20) -> smooth -> reduce={'model':'UMAP','params':{'n_neighbors':36,'min_dist':0.1,'random_state':42}} -> **animate='spin'** (NOT window), duration=30, frame_rate=30, rotations=1, linewidth=3, zoom=2, size=[8,6].
153-
- CORRECTION vs 2317cd5: had shipped n_neighbors=150; Jeremy: that gives "a straight (slightly curved) line, with no dramatic bends" — download.png has a LOOP. Swept nn={15,30,36,50,80,150} x min_dist x seeds vs download.png. nn=15 hairball; nn=150 over-globalizes -> flattens loop; **nn=36 md=0.1 = tight bundle WITH the loop** (best qualitative match). Also switched window animation (animate=True + tail_duration=4) -> animate='spin': window only ever showed a rolling 4s fragment (tangle), never the full loop; spin draws the whole bundle and orbits so the loop is always visible.
153+
- CORRECTION vs 2317cd5: had shipped n_neighbors=150; Jeremy: that gives "a straight (slightly curved) line, with no dramatic bends" — download.png has a LOOP. Swept nn={15,30,36,50,80,150} x min_dist x seeds vs download.png. nn=15 hairball; nn=150 over-globalizes -> flattens loop; **nn=36 md=0.1 = tight bundle WITH the loop** (best qualitative match).
154+
- ANIMATION STYLE (Jeremy, round 4.6): sliding window (animate=True + tail_duration=4), NOT spin (briefly shipped spin in b362d67; reverted). CRITICAL REQUIREMENT: the view/space inside the cube must be FIXED across the full animation — must not depend on which window is visible. Already guaranteed by implementation: helpers.scale() normalizes once from the FULL stacked data (plot.py:614) and update_lines_parallel never touches limits; VERIFIED programmatically (limits identical across frames: +/-1.15/+/-1.04, while fragment x-extent slides -0.99..0.04 -> 0.36..1.00 -> -0.80..-0.11).
154155
- PROVED it's a pure UMAP-n_neighbors effect, not a version/alignment artifact: (a) modern SRM branch align.py:137 SRM(features=min shape[0]) re-fit per pass is byte-identical to era 0.6.2 align.py SRM branch; (b) built era venv (uv, py3.9, numba 0.55, umap-learn 0.4.6, patched layouts.py int32->intp) and fit 0.4.6 on the SAME modern-aligned data -> ALSO a hairball at its default nn=15. So old deps don't recover the look; neighborhood tuning does. Byte-exact era repro infeasible on arm64 (ht 0.6.2 pins sklearn 0.21.3, won't build). download.png = DESIRED look, acceptance qualitative (bundle + loop, not a straight line). Cached: /tmp/aligned_weights.npz (modern SRM x20 aligned), /tmp/raw_weights.npz.
155156
- SRM corr plateaus 0.87 (shared-signal ceiling; SRM unchanged since v0.6.2).
156157
- align('SRM') n_iter support; hyperalign per-pass rescale (collapse fix).

scripts/generate_weights_trajectory.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ def main():
5252
reduce={'model': 'UMAP',
5353
'params': {'n_neighbors': 36, 'min_dist': 0.1,
5454
'random_state': 42}},
55-
# spin (not window) so the complete looping bundle stays on
56-
# screen and orbits in 3D -- the classic readthedocs gif style;
57-
# a rolling window would only ever show a tangled fragment
58-
animate='spin', duration=30, frame_rate=30,
55+
# sliding-window animation in a FIXED space: the data are
56+
# scaled once from the full dataset (helpers.scale), so the
57+
# axis limits never depend on which window is visible -- the
58+
# comet travels along the loop while the cube's contents stay
59+
# put (verified: limits identical across frames)
60+
animate=True, duration=30, frame_rate=30, tail_duration=4,
5961
rotations=1, linewidth=3, zoom=2, size=[8, 6],
6062
save_path=mp4, show=False)
6163
# the dense spinning bundle (36 fat trajectories every frame) is large;

0 commit comments

Comments
 (0)