Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
69be48a
Design spec: HyperTools 2.0 class-based refactor
jeremymanning Jul 3, 2026
f86f185
Plan 1: datawrangler adoption & verification (2.0 refactor step 0)
jeremymanning Jul 3, 2026
bb993fd
Plan 1: incorporate verified env facts (.venv, pandas<3 pin, dw#30, d…
jeremymanning Jul 3, 2026
9612e88
build: add datawrangler dep; pin pandas <3 for dw 0.4.0 (data-wrangle…
jeremymanning Jul 3, 2026
a419634
test: probe datawrangler API surface (symbol existence)
jeremymanning Jul 3, 2026
aa0efb3
test: probe datawrangler behavior (stack/unstack, funnel, polars, text)
jeremymanning Jul 3, 2026
4c60d76
ci: run on dev-2.0-refactor; seed datawrangler coordination log (dw#30)
jeremymanning Jul 3, 2026
3c6b1f4
Plan 2: core layer (exceptions/shared/configurator/model) — additive …
jeremymanning Jul 3, 2026
268d0a8
refactor(core): move exceptions to hypertools.core; shim _shared
jeremymanning Jul 3, 2026
6c364cf
feat(core): add RobustDict and eval-free unpack_model
jeremymanning Jul 3, 2026
1ccf632
feat(core): central config.ini defaults via datawrangler configurator
jeremymanning Jul 3, 2026
b89ad8d
refactor(core): relocate apply_model to core.model; accept fork dict …
jeremymanning Jul 3, 2026
a10bb08
Notes: Plans 1-2 complete (dw adoption + core layer); Plan 3 design a…
jeremymanning Jul 3, 2026
78ce4cd
Plan 3: external/ + manip/ (compat-wrapper design)
jeremymanning Jul 3, 2026
015d75c
refactor(external): quarantine vendored ppca+srm in hypertools.extern…
jeremymanning Jul 3, 2026
d1ae8c5
feat(core): add get() elementwise list indexer (Resample prereq)
jeremymanning Jul 3, 2026
b7db98a
feat(manip): add Manipulator base class
jeremymanning Jul 3, 2026
cbafc3d
feat(manip): add Normalize (min-max) and ZScore manipulators
jeremymanning Jul 3, 2026
22def74
feat(manip): add Smooth (savgol) and Resample (pchip) + manip dispatcher
jeremymanning Jul 3, 2026
536ed32
fix(manip): axis=1 transpose recursion double-stacked via decorator (…
jeremymanning Jul 3, 2026
0976879
feat(api): expose hyp.manip; hyp.normalize compat unchanged
jeremymanning Jul 3, 2026
60b598f
build(deps): upgrade datawrangler 0.4.0->0.5.0, lift pandas<3 pin (pa…
jeremymanning Jul 3, 2026
8826124
docs(plan): add Plan 4 (reduce+align+cluster) implementation plan
jeremymanning Jul 3, 2026
da576ec
refactor(reduce): re-home reduce+describe into hypertools.reduce; shi…
jeremymanning Jul 3, 2026
9e985ba
feat(align): add Aligner base + pad/trim_and_pad helpers
jeremymanning Jul 3, 2026
c613e2e
feat(align): add procrustes fn + Procrustes/NullAlign children; shim …
jeremymanning Jul 4, 2026
dd235b9
feat(align): add HyperAlign (dev-2.0 rescaled hyperalignment algorithm)
jeremymanning Jul 4, 2026
5be6ca2
feat(align): add SRM + DetSRM adapters over external.brainiak (RSRM n…
jeremymanning Jul 4, 2026
22cab2b
feat(align): add align dispatcher + classic tools/align compat shim
jeremymanning Jul 4, 2026
49a87c6
refactor(cluster): re-home cluster into hypertools.cluster; shim tools
jeremymanning Jul 4, 2026
a24f36b
refactor(io): re-home load+sources+streaming into hypertools.io; shim…
jeremymanning Jul 4, 2026
cceccd1
docs(plan): add Plan 5 (io) implementation plan
jeremymanning Jul 4, 2026
e23be72
docs(plan): Plan 5 save.py = plain pickle (dw.io.save has reversed ar…
jeremymanning Jul 4, 2026
f07b1f3
feat(io): add data-serialization save + expose hyp.save/hyp.io; close…
jeremymanning Jul 4, 2026
f0276c7
docs(plan): add Plan 6 (plot reorg + colors + gaussian Smooth) implem…
jeremymanning Jul 4, 2026
b364cdc
feat(manip): add gaussian mode to Smooth (var=300, sigma=sqrt(var)) f…
jeremymanning Jul 4, 2026
dc71d2a
refactor(plot): consolidate coloring into plot.colors; shim tools.colors
jeremymanning Jul 4, 2026
304d1cc
refactor(plot): rename draw->matplotlib_backend, interactive->plotly_…
jeremymanning Jul 4, 2026
787b763
refactor(plot): extract animation save helpers into plot.animate; clo…
jeremymanning Jul 4, 2026
66dfc2e
docs(plan): add Plan 7 (DataGeometry removal + API finalization)
jeremymanning Jul 4, 2026
f8b5407
refactor(tools): repoint production imports off tools.* shims to real…
jeremymanning Jul 4, 2026
12a53de
refactor(tools): retire 9 re-export shims; repoint tests to real modules
jeremymanning Jul 4, 2026
a742225
feat(align): vendor RSRM + RobustSharedResponseModel adapter
jeremymanning Jul 4, 2026
508fbe7
feat(plot): return figure/(fig,ani) + return_model bundle; drop DataG…
jeremymanning Jul 4, 2026
9bbdb9e
feat(io): streaming plots carry fig.stream_info; rewrite test_streaming
jeremymanning Jul 4, 2026
71d3e75
chore(scripts): add example-dataset re-host regeneration script
jeremymanning Jul 4, 2026
9a9353b
refactor(geo): hide DataGeometry as internal unpickle-only class; loa…
jeremymanning Jul 4, 2026
a5a1cf9
docs(plan): add Plan 8 (docs/gallery/notebooks migration + Playwright…
jeremymanning Jul 4, 2026
310e127
docs(examples): migrate 20 gallery examples to figure-return / raw-lo…
jeremymanning Jul 4, 2026
3587310
docs: repurpose geo example to the 2.0 return model (DataGeometry rem…
jeremymanning Jul 4, 2026
1dbe999
docs(tutorials): migrate 13 tutorials to 2.0 figure-return API + re-e…
jeremymanning Jul 4, 2026
3de22f5
fix(plot): plotly ',' (and all mpl markers) render as markers; legend…
jeremymanning Jul 4, 2026
a1e6526
docs(examples): add shapes-zoo morphing gallery example
jeremymanning Jul 4, 2026
a8585cb
fix(plot): exported animation gifs preserve real-time duration (were …
jeremymanning Jul 4, 2026
d987a7d
docs: rebuild gallery+API under 2.0 API (figure-return, no geo); fix …
jeremymanning Jul 4, 2026
a57548a
docs: Playwright visual verification of built docs + PR evidence
jeremymanning Jul 4, 2026
764e6d7
fix: address whole-branch review findings (load dict-arg crash + 4 mi…
jeremymanning Jul 4, 2026
346ddc6
fix(plot): zoom out animated plots slightly so the bounding box is ne…
jeremymanning Jul 4, 2026
a16cf34
fix(plot): exclude animation trails from the legend (no duplicate ent…
jeremymanning Jul 4, 2026
bb12cd8
fix: address 6 bugs surfaced by open-issue triage against dev-2.0
jeremymanning Jul 4, 2026
fa8a643
docs: regenerate animated gallery with the anim zoom-out + legend fix
jeremymanning Jul 4, 2026
538db81
docs(notes): issue-triage catalog + animation-fix PR evidence
jeremymanning Jul 4, 2026
c4abaee
fix(ci): Windows dw import, mpl-3.11 canvas access, and robust legend…
jeremymanning Jul 4, 2026
4b5048e
test: pixel-based regression for wide-legend clipping (saved image)
jeremymanning Jul 4, 2026
9433f99
docs: regenerate legend gallery examples with the widen-to-fit legend…
jeremymanning Jul 4, 2026
0617424
docs(notes): session log for CI-green + legend fixes + dw#32 coordina…
jeremymanning Jul 4, 2026
fb1cb03
fix(ci): keep animated figures open on show=False; harness uses retur…
jeremymanning Jul 4, 2026
80470fd
deps: require pydata-wrangler>=0.5.1 (Windows import fix released ups…
jeremymanning Jul 4, 2026
92110f4
docs(notes): round-2 CI fixes (animated-close exemption, harness, dw …
jeremymanning Jul 4, 2026
e3530a6
chore: renumber release 2.0 -> 1.0 (version, docs, branches, artifacts)
jeremymanning Jul 5, 2026
17e1bf5
docs(notes): round-3 log — 2.0 -> 1.0 renumber, branch renames, PR #2…
jeremymanning Jul 5, 2026
ecacef7
plan: hyp.predict + hyp.impute implementation plan (GH #169)
jeremymanning Jul 5, 2026
7db0771
feat(predict): Forecaster base + GH#169 t semantics
jeremymanning Jul 5, 2026
a61179b
plan(predict): return_model=(result, fitted) contract, reusable on ne…
jeremymanning Jul 5, 2026
6922ff5
feat(predict): Kalman, GaussianProcess, AutoRegressor forecasters
jeremymanning Jul 5, 2026
6e4a18c
feat(predict): ARIMA + skaters Laplace forecasters
jeremymanning Jul 5, 2026
c45450b
feat(predict): Chronos forecaster + hyp.predict dispatcher with retur…
jeremymanning Jul 5, 2026
45f65ad
feat(impute): PPCA/sklearn/Kalman imputers + hyp.impute dispatcher (G…
jeremymanning Jul 5, 2026
df68b5a
feat(plot,analyze): predict= and impute= integration
jeremymanning Jul 5, 2026
912ac84
deps: [predict] and [predict-hf] extras; predict deps in dev + doc bu…
jeremymanning Jul 5, 2026
4d264df
fix(plot): scale forecasts into the plot frame (2D+3D)
jeremymanning Jul 5, 2026
0de6b21
docs(gallery): plot_predict + plot_impute examples; predict/impute AP…
jeremymanning Jul 5, 2026
1081ef6
docs(gallery): plot_predict uses helical data so forecasts are visible
jeremymanning Jul 5, 2026
0e313a0
docs(tutorials): stock forecasting tutorial (real yfinance data, hone…
jeremymanning Jul 5, 2026
2eda5b9
docs(tutorials): Kalman projectile tutorial (real SportVU jump-shot arc)
jeremymanning Jul 5, 2026
4585987
docs(notes): #169 implemented (hyp.predict + hyp.impute) -- move to f…
jeremymanning Jul 5, 2026
bbb96b4
docs: build gallery with plot_predict + plot_impute (and 1.0-rename r…
jeremymanning Jul 5, 2026
04c10e2
fix(predict,format_data): GP forecasts extrapolate trends; align df c…
jeremymanning Jul 5, 2026
18a6d91
docs: regenerate plot_predict gallery (trend-extrapolating forecasts)…
jeremymanning Jul 5, 2026
8d424e0
fix(plot): colors= kwarg was a no-op unless color= also passed (GH #142)
jeremymanning Jul 5, 2026
26dec4f
fix(plot): linestyles=/markers= aliases were no-ops without singular …
jeremymanning Jul 5, 2026
f150750
feat(io): complete hyp.load -- Drive large files, Excel, Sheets CSV, …
jeremymanning Jul 5, 2026
9aff4c5
fix(io): scope trust-policy re-raise to HypertoolsTrustError, not all…
jeremymanning Jul 5, 2026
8adedc9
feat(plot): colorbar support for continuous hue and discrete groups (…
jeremymanning Jul 5, 2026
be1e44d
feat(plot): mesh utilities for smooth convex-hull surfaces (GH #109)
jeremymanning Jul 5, 2026
4ef198c
feat(plot): smooth convex-hull surfaces with lighting, dict API (GH #…
jeremymanning Jul 5, 2026
30dac24
fix(plotly): trail frame updates tracked by explicit trace indices, n…
jeremymanning Jul 5, 2026
7766a5e
docs(examples): surface-morph demo showcasing hull surfaces (GH #109)
jeremymanning Jul 5, 2026
f8e8bfe
feat(plot): subtle KDE density shading, off by default (GH #108, GH #…
jeremymanning Jul 5, 2026
c805b26
fix(density): wire levels knob, validate option values (GH #108)
jeremymanning Jul 5, 2026
15e9753
feat(animate): per-dataset chemtrails/precog/bullettime (GH #127)
jeremymanning Jul 5, 2026
85f263d
feat(plot): MultiIndex DataFrames -- leaf traces + per-level averages…
jeremymanning Jul 5, 2026
188b63a
fix(multiindex): warn on list-input bypass, error on predict= combo, …
jeremymanning Jul 5, 2026
db9edfe
fix(surface): plotly opaque-color blend + mesh/marker occlusion fixes…
jeremymanning Jul 6, 2026
925e0b4
fix(surface): contain meshes within axes cube; clean plotly intersect…
jeremymanning Jul 6, 2026
fd064aa
fix(surface): plotly surfaces use precomputed vertex shading (matches…
jeremymanning Jul 6, 2026
fcd8f96
fix(colorbar,multiindex): top-level colorbar segments; legend fitting…
jeremymanning Jul 6, 2026
4fd9e65
fix(density): auto-boost 3D shell/volume opacity for small-in-scene c…
jeremymanning Jul 6, 2026
a5be240
fix(animate): warn + skip trail styles under spin/serial modes (GH #127)
jeremymanning Jul 6, 2026
3d320c4
docs(examples): gallery examples for surfaces, density, colorbars, Mu…
jeremymanning Jul 6, 2026
61bf92a
docs: regenerate gallery with new examples; fix morph animations' fig…
jeremymanning Jul 6, 2026
3861ca6
docs: track impute/predict api stubs (match module-stub convention); …
jeremymanning Jul 6, 2026
eaf7fca
notes: move #108/#191 to fixed list, drop duplicate #109 leave-open r…
jeremymanning Jul 6, 2026
c0eff29
fix(surface): tight hulls — no blanket inflation, bounded containment…
jeremymanning Jul 6, 2026
d39a4ef
fix(tests): version-robust Poly3DCollection vertex extraction (_vec/_…
jeremymanning Jul 6, 2026
c8af7b5
feat(meshutil): hull-hugging smoothing — pull smoothed verts back to …
jeremymanning Jul 6, 2026
b52b5b8
feat(animate): morph animation style — Hungarian point-cloud morphs b…
jeremymanning Jul 6, 2026
e1df010
docs(examples): shape morphs use first-class animate='morph' (+surfac…
jeremymanning Jul 6, 2026
b6074f7
fix(morph): size axes cube from union-hull mesh so surfaces stay insi…
jeremymanning Jul 6, 2026
d71da01
fix(morph): size surface box from sampled/union meshes only; correct …
jeremymanning Jul 6, 2026
f3e044b
fix(morph): untagged datasets render fully in mpl mixed-tag morph ani…
jeremymanning Jul 6, 2026
987fb5e
docs: regenerate gallery — morph demos as animate='morph' videos; hul…
jeremymanning Jul 6, 2026
488b929
notes: round-3 session log (morph animation + tight hulls)
jeremymanning Jul 6, 2026
e7becfe
fix(tests): widen meshutil runtime guard for slow CI runners (0.5s ->…
jeremymanning Jul 6, 2026
108c08b
fix(morph): constant rotation speed — segment duration proportional t…
jeremymanning Jul 6, 2026
ec4d5fa
fix(plotly): marker sizes calibrated to matplotlib; more transparent …
jeremymanning Jul 6, 2026
0eac418
fix(surface): remove orphaned roughness/fresnel lighting keys, add li…
jeremymanning Jul 6, 2026
188d301
docs: regenerate gallery — constant-speed morph videos + recalibrated…
jeremymanning Jul 6, 2026
4f68689
docs: refresh spin.gif build artifact from gallery re-execution
jeremymanning Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 15 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Tests

on:
push:
branches: [ master, dev, dev-2.0 ]
branches: [ master, dev, dev-1.0, dev-1.0-refactor ]
pull_request:
branches: [ master, dev ]

Expand All @@ -13,6 +13,10 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
# datawrangler 0.5.0+ supports pandas 3.0 (dw#30/#31) and py3.10-3.13. The pandas<3
# ceiling is lifted, so the resolver naturally picks pandas 3.x on py3.11-3.13 and
# pandas 2.x on py3.10 (pandas 3.0 requires py>=3.11) -- the matrix exercises both.
# A dedicated pinned-pandas-3 gate runs below on ubuntu/py3.12.
python-version: ['3.10', '3.11', '3.12', '3.13']

steps:
Expand Down Expand Up @@ -69,6 +73,16 @@ jobs:
run: |
pytest -v --tb=short

- name: Acceptance gate — pandas 3.0 (Ubuntu Python 3.12 only)
# Guarantees a pandas-3 run regardless of resolver choices (dw#30/#31 fix).
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
env:
MPLBACKEND: Agg
run: |
pip install "pandas>=3.0"
python -c "import pandas as pd; assert pd.__version__.split('.')[0] == '3', pd.__version__; print('pandas', pd.__version__)"
pytest -q

- name: Run pytest with coverage (Ubuntu Python 3.12 only)
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
env:
Expand Down
Binary file modified dev/animation_demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 5 additions & 5 deletions dev/hypertools_2.0_dev.ipynb → dev/hypertools_1.0_dev.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "# HyperTools 2.0 dev/testing notebook\n\nInteractive companion to the `dev-2.0` modernization branch (see `notes/hypertools_2.0_roadmap.md`).\n\n**Purpose:** exercise EVERY public function across the full use-case matrix, visually verify output, and compare backends. Each section corresponds to one public API function. Run top-to-bottom in Jupyter, Colab, or Kaggle — the three environments we must support.\n\n**Use-case matrix** (applied to each function where relevant):\n\n| dimension | cases |\n|-|-|\n| input type | single ndarray, list of ndarrays, DataFrame, list of DataFrames, nested lists (→ MultiIndex), text |\n| dimensionality | 2D, 3D, high-D (reduced), 1D edge case |\n| missing data | none, NaNs (PPCA fill) |\n| styling | fmt strings, hue/group, legend, labels, title, multilevel-index color/thickness/opacity |\n| coloring | categorical labels, continuous values, mixture proportions, user matrices, multicolored lines |\n| models | reduce (PCA/IncrementalPCA/TSNE/UMAP), cluster (KMeans/HDBSCAN), mixtures (GaussianMixture/BayesianGaussianMixture/LDA/NMF), align (hyper/SRM) |\n| animation | static, animate=True, spin, sliding window |\n| backend | matplotlib (default), plotly (interactive) — 2.0 feature |"
"source": "# HyperTools 1.0 dev/testing notebook\n\nInteractive companion to the `dev-1.0` modernization branch (see `notes/hypertools_1.0_roadmap.md`).\n\n**Purpose:** exercise EVERY public function across the full use-case matrix, visually verify output, and compare backends. Each section corresponds to one public API function. Run top-to-bottom in Jupyter, Colab, or Kaggle — the three environments we must support.\n\n**Use-case matrix** (applied to each function where relevant):\n\n| dimension | cases |\n|-|-|\n| input type | single ndarray, list of ndarrays, DataFrame, list of DataFrames, nested lists (→ MultiIndex), text |\n| dimensionality | 2D, 3D, high-D (reduced), 1D edge case |\n| missing data | none, NaNs (PPCA fill) |\n| styling | fmt strings, hue/group, legend, labels, title, multilevel-index color/thickness/opacity |\n| coloring | categorical labels, continuous values, mixture proportions, user matrices, multicolored lines |\n| models | reduce (PCA/IncrementalPCA/TSNE/UMAP), cluster (KMeans/HDBSCAN), mixtures (GaussianMixture/BayesianGaussianMixture/LDA/NMF), align (hyper/SRM) |\n| animation | static, animate=True, spin, sliding window |\n| backend | matplotlib (default), plotly (interactive) — 2.0 feature |"
},
{
"cell_type": "code",
Expand All @@ -19,7 +19,7 @@
"\n",
"t0 = time.time()\n",
"import hypertools as hyp\n",
"print(f'hypertools {hyp.__version__} imported in {time.time()-t0:.2f}s') # 2.0 target: < 1s\n",
"print(f'hypertools {hyp.__version__} imported in {time.time()-t0:.2f}s') # 1.0 target: < 1s\n",
"\n",
"ENV = 'colab' if 'google.colab' in sys.modules else ('kaggle' if os.path.exists('/kaggle') else 'local')\n",
"print('environment:', ENV)"
Expand Down Expand Up @@ -78,7 +78,7 @@
"source": [
"## 3. `hyp.plot` — animation\n",
"\n",
"Known-broken on master: numpy>=2 Jupyter animations (#265), Colab `animate=True` (#235), figures in loops (#264). These cells are the acceptance tests for the 2.0 fixes."
"Known-broken on master: numpy>=2 Jupyter animations (#265), Colab `animate=True` (#235), figures in loops (#264). These cells are the acceptance tests for the 1.0 fixes."
]
},
{
Expand All @@ -91,14 +91,14 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "## 4. `hyp.plot` — 2.0 features (IMPLEMENTED on dev-2.0)\n\nBackend switching, nested-list multilevel styling, mixture-model soft clustering, and matrix-valued hue. Each of these also has pytest coverage (`test_interactive.py`, `test_nested.py`, `test_colors.py`, `test_cluster.py`) and screenshot-harness cases."
"source": "## 4. `hyp.plot` — 1.0 features (IMPLEMENTED on dev-1.0)\n\nBackend switching, nested-list multilevel styling, mixture-model soft clustering, and matrix-valued hue. Each of these also has pytest coverage (`test_interactive.py`, `test_nested.py`, `test_colors.py`, `test_cluster.py`) and screenshot-harness cases."
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "# --- backend switching (approved policy: plotly only on Colab/Kaggle) ---\nhyp.plot(walk, backend='matplotlib') # explicit classic renderer\nfig = hyp.plot(walk, backend='plotly') # interactive plotly renderer\nhyp.plot(walk, backend='auto') # plotly on Colab/Kaggle, else matplotlib\n\n# --- plotly ANIMATIONS: interactive frames in the notebook, exportable to\n# gif / animated png / mp4 exactly like the matplotlib backend ---\ngeo = hyp.plot(walk, animate=True, duration=3, backend='plotly') # play button\nhyp.plot(walk, animate='spin', duration=3, backend='plotly',\n save_path='plotly_spin_demo.gif', show=False)\nfrom IPython.display import Image as IPyImage\ndisplay(IPyImage('plotly_spin_demo.gif'))\n\n# --- nested lists -> multilevel styling (color by outer group; deeper\n# leaves render thinner + fainter) ---\nhyp.plot([[walk, walk2], [np.cumsum(np.random.default_rng(7).standard_normal((200, 10)), axis=0)]])\n\n# --- mixture models on OVERLAPPING clusters: multi-class membership shows\n# as blended (intermediate) colors between components ---\nprops = hyp.cluster(oclusters, cluster='GaussianMixture', n_clusters=3)\nsoft = np.mean(props.max(axis=1) < 0.9)\nprint(f'mixture proportions: {props.shape}; {soft:.0%} of points have genuinely mixed membership')\nhyp.plot(oclusters, 'o', cluster='GaussianMixture', n_clusters=3)\n\n# --- robust coloring: matrix-valued hue (proportions, weights, any matrix) ---\nhyp.plot(oclusters, 'o', hue=props)\nhyp.plot(walk, 'o', hue=np.arange(len(walk), dtype=float)) # continuous hue\n\n# --- MULTICOLORED LINES: continuous/matrix hue + line fmt colors each\n# trajectory continuously along its length (both backends) ---\nhyp.plot(walk, hue=np.arange(len(walk), dtype=float))\nhyp.plot(walk, hue=np.arange(len(walk), dtype=float), backend='plotly')\n\n# --- apply_model: stack -> fit once -> unstack core ---\nembedded = hyp.apply_model([walk, walk2], 'PCA', ndims=3)\nprint('shared embedding:', [e.shape for e in embedded])\n\n# --- retired in 2.0 (raise clear errors now): plot(group=...), plot(model=...),\n# reduce(model=/align=/normalize=), align(method=/align=True), cluster(ndims=) ---"
"source": "# --- backend switching (approved policy: plotly only on Colab/Kaggle) ---\nhyp.plot(walk, backend='matplotlib') # explicit classic renderer\nfig = hyp.plot(walk, backend='plotly') # interactive plotly renderer\nhyp.plot(walk, backend='auto') # plotly on Colab/Kaggle, else matplotlib\n\n# --- plotly ANIMATIONS: interactive frames in the notebook, exportable to\n# gif / animated png / mp4 exactly like the matplotlib backend ---\ngeo = hyp.plot(walk, animate=True, duration=3, backend='plotly') # play button\nhyp.plot(walk, animate='spin', duration=3, backend='plotly',\n save_path='plotly_spin_demo.gif', show=False)\nfrom IPython.display import Image as IPyImage\ndisplay(IPyImage('plotly_spin_demo.gif'))\n\n# --- nested lists -> multilevel styling (color by outer group; deeper\n# leaves render thinner + fainter) ---\nhyp.plot([[walk, walk2], [np.cumsum(np.random.default_rng(7).standard_normal((200, 10)), axis=0)]])\n\n# --- mixture models on OVERLAPPING clusters: multi-class membership shows\n# as blended (intermediate) colors between components ---\nprops = hyp.cluster(oclusters, cluster='GaussianMixture', n_clusters=3)\nsoft = np.mean(props.max(axis=1) < 0.9)\nprint(f'mixture proportions: {props.shape}; {soft:.0%} of points have genuinely mixed membership')\nhyp.plot(oclusters, 'o', cluster='GaussianMixture', n_clusters=3)\n\n# --- robust coloring: matrix-valued hue (proportions, weights, any matrix) ---\nhyp.plot(oclusters, 'o', hue=props)\nhyp.plot(walk, 'o', hue=np.arange(len(walk), dtype=float)) # continuous hue\n\n# --- MULTICOLORED LINES: continuous/matrix hue + line fmt colors each\n# trajectory continuously along its length (both backends) ---\nhyp.plot(walk, hue=np.arange(len(walk), dtype=float))\nhyp.plot(walk, hue=np.arange(len(walk), dtype=float), backend='plotly')\n\n# --- apply_model: stack -> fit once -> unstack core ---\nembedded = hyp.apply_model([walk, walk2], 'PCA', ndims=3)\nprint('shared embedding:', [e.shape for e in embedded])\n\n# --- retired in 1.0 (raise clear errors now): plot(group=...), plot(model=...),\n# reduce(model=/align=/normalize=), align(method=/align=True), cluster(ndims=) ---"
},
{
"cell_type": "markdown",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"id": "a788b512",
"metadata": {},
"source": [
"# HyperTools 2.0 dev/testing notebook\n",
"# HyperTools 1.0 dev/testing notebook\n",
"\n",
"Interactive companion to the `dev-2.0` modernization branch (see `notes/hypertools_2.0_roadmap.md`).\n",
"Interactive companion to the `dev-1.0` modernization branch (see `notes/hypertools_1.0_roadmap.md`).\n",
"\n",
"**Purpose:** exercise EVERY public function across the full use-case matrix, visually verify output, and compare backends. Each section corresponds to one public API function. Run top-to-bottom in Jupyter, Colab, or Kaggle — the three environments we must support.\n",
"\n",
Expand Down Expand Up @@ -42,7 +42,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"hypertools 2.0.0.dev0 imported in 3.86s\n",
"hypertools 1.0.0.dev0 imported in 3.86s\n",
"environment: local\n"
]
}
Expand All @@ -56,7 +56,7 @@
"\n",
"t0 = time.time()\n",
"import hypertools as hyp\n",
"print(f'hypertools {hyp.__version__} imported in {time.time()-t0:.2f}s') # 2.0 target: < 1s\n",
"print(f'hypertools {hyp.__version__} imported in {time.time()-t0:.2f}s') # 1.0 target: < 1s\n",
"\n",
"ENV = 'colab' if 'google.colab' in sys.modules else ('kaggle' if os.path.exists('/kaggle') else 'local')\n",
"print('environment:', ENV)"
Expand Down Expand Up @@ -163,7 +163,7 @@
"source": [
"## 3. `hyp.plot` — animation\n",
"\n",
"Known-broken on master: numpy>=2 Jupyter animations (#265), Colab `animate=True` (#235), figures in loops (#264). These cells are the acceptance tests for the 2.0 fixes."
"Known-broken on master: numpy>=2 Jupyter animations (#265), Colab `animate=True` (#235), figures in loops (#264). These cells are the acceptance tests for the 1.0 fixes."
]
},
{
Expand Down Expand Up @@ -37291,7 +37291,7 @@
"id": "1ca254ea",
"metadata": {},
"source": [
"## 4. `hyp.plot` — 2.0 features (IMPLEMENTED on dev-2.0)\n",
"## 4. `hyp.plot` — 1.0 features (IMPLEMENTED on dev-1.0)\n",
"\n",
"Backend switching, nested-list multilevel styling, mixture-model soft clustering, and matrix-valued hue. Each of these also has pytest coverage (`test_interactive.py`, `test_nested.py`, `test_colors.py`, `test_cluster.py`) and screenshot-harness cases."
]
Expand Down Expand Up @@ -44449,7 +44449,7 @@
"embedded = hyp.apply_model([walk, walk2], 'PCA', ndims=3)\n",
"print('shared embedding:', [e.shape for e in embedded])\n",
"\n",
"# --- retired in 2.0 (raise clear errors now): plot(group=...), plot(model=...),\n",
"# --- retired in 1.0 (raise clear errors now): plot(group=...), plot(model=...),\n",
"# reduce(model=/align=/normalize=), align(method=/align=True), cluster(ndims=) ---"
]
},
Expand Down
Binary file modified dev/plotly_spin_demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 17 additions & 11 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@
API reference
=============

.. _plot_api:

DataGeometry class
------------------

.. autosummary::
:toctree:

hypertools.DataGeometry

Load
------------------

Expand Down Expand Up @@ -73,6 +63,22 @@ Cluster

hypertools.cluster

Predict
------------------

.. autosummary::
:toctree:

hypertools.predict

Impute
------------------

.. autosummary::
:toctree:

hypertools.impute

Apply model
------------------

Expand All @@ -99,7 +105,7 @@ Tools
.. autosummary::
:toctree:

hypertools.tools.procrustes
hypertools.align.procrustes

.. autosummary::
:toctree:
Expand Down
32 changes: 0 additions & 32 deletions docs/auto_examples/analyze.codeobj.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,6 @@
"name": "list"
}
],
"geo": [
{
"is_class": false,
"is_explicit": false,
"module": "hypertools.datageometry",
"module_short": "hypertools",
"name": "DataGeometry"
},
{
"is_class": false,
"is_explicit": false,
"module": "hypertools",
"module_short": "hypertools",
"name": "DataGeometry"
}
],
"geo.get_data": [
{
"is_class": false,
"is_explicit": false,
"module": "hypertools.datageometry",
"module_short": "hypertools",
"name": "DataGeometry.get_data"
},
{
"is_class": false,
"is_explicit": false,
"module": "hypertools",
"module_short": "hypertools",
"name": "DataGeometry.get_data"
}
],
"hyp.analyze": [
{
"is_class": false,
Expand Down
108 changes: 52 additions & 56 deletions docs/auto_examples/analyze.ipynb
Original file line number Diff line number Diff line change
@@ -1,58 +1,54 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Install hypertools (dev-2.0 preview) -- run this first on Colab.\n",
"# On release this becomes: %pip install hypertools\n",
"%pip install -q \"hypertools[interactive] @ git+https://github.com/ContextLab/hypertools.git@dev-2.0\"\n",
"\n",
"%matplotlib inline"
]
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Install hypertools (dev-1.0-refactor preview) -- run this first on Colab.\n# On release this becomes: %pip install hypertools\n%pip install -q \"hypertools[interactive] @ git+https://github.com/ContextLab/hypertools.git@dev-1.0-refactor\"\n\n%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n# Analyze data and then plot\n\nThis example demonstrates how to use the `analyze` function to process data\nprior to plotting. The data is a list of numpy arrays representing\nmulti-voxel activity patterns (columns) over time (rows). First, analyze function\nnormalizes the columns of each matrix (within each matrix). Then the data is\nreduced using PCA (10 dims) and finally it is aligned with hyperalignment. We can\nthen plot the data with hyp.plot, which further reduces it so that it can be\nvisualized.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_analyze_thumb.png'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# load hypertools\nimport hypertools as hyp\n\n# load the data\ndata = hyp.load('weights')\n\n# process the data\ndata = hyp.analyze(data, normalize='within', reduce='PCA', ndims=10,\n align='hyper')\n\n# plot it\nhyp.plot(data)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n# Analyze data and then plot\n\nThis example demonstrates how to use the `analyze` function to process data\nprior to plotting. The data is a list of numpy arrays representing\nmulti-voxel activity patterns (columns) over time (rows). First, analyze function\nnormalizes the columns of each matrix (within each matrix). Then the data is\nreduced using PCA (10 dims) and finally it is aligned with hyperalignment. We can\nthen plot the data with hyp.plot, which further reduces it so that it can be\nvisualized.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_analyze_thumb.png'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# load hypertools\nimport hypertools as hyp\n\n# load the data\ngeo = hyp.load('weights')\ndata = geo.get_data()\n\n# process the data\ndata = hyp.analyze(data, normalize='within', reduce='PCA', ndims=10,\n align='hyper')\n\n# plot it\nhyp.plot(data)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
"nbformat": 4,
"nbformat_minor": 0
}
3 changes: 1 addition & 2 deletions docs/auto_examples/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
import hypertools as hyp

# load the data
geo = hyp.load('weights')
data = geo.get_data()
data = hyp.load('weights')

# process the data
data = hyp.analyze(data, normalize='within', reduce='PCA', ndims=10,
Expand Down
2 changes: 1 addition & 1 deletion docs/auto_examples/analyze.py.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b188d6db61e339db0651634314ffdc5a
68992cc2797469b2fefb43fcf35a16d6
7 changes: 3 additions & 4 deletions docs/auto_examples/analyze.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ reduced using PCA (10 dims) and finally it is aligned with hyperalignment. We ca
then plot the data with hyp.plot, which further reduces it so that it can be
visualized.

.. GENERATED FROM PYTHON SOURCE LINES 15-34
.. GENERATED FROM PYTHON SOURCE LINES 15-33



Expand All @@ -55,8 +55,7 @@ visualized.
import hypertools as hyp

# load the data
geo = hyp.load('weights')
data = geo.get_data()
data = hyp.load('weights')

# process the data
data = hyp.analyze(data, normalize='within', reduce='PCA', ndims=10,
Expand All @@ -68,7 +67,7 @@ visualized.

.. rst-class:: sphx-glr-timing

**Total running time of the script:** (0 minutes 0.389 seconds)
**Total running time of the script:** (0 minutes 0.374 seconds)


.. _sphx_glr_download_auto_examples_analyze.py:
Expand Down
Binary file modified docs/auto_examples/analyze.zip
Binary file not shown.
Loading
Loading