Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
243 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
b8c4bbe
test(morph): add bbox-margin regression guard for all animate styles …
jeremymanning Jul 6, 2026
b461fee
fix(animate): render correctly at any save dpi (sphinx-gallery gif th…
jeremymanning Jul 6, 2026
a3df5cd
feat(morph): full-sample morphs — duplicate to largest dataset, hide …
jeremymanning Jul 6, 2026
9aa5c85
docs: regenerate all animated gallery examples — correct gif thumbnai…
jeremymanning Jul 6, 2026
3d5d79a
fix(tests): CI-robust manager-restore ordering + explicit Agg canvase…
jeremymanning Jul 6, 2026
d8e37c0
test(animate): add chemtrails/PCHIP-overshoot regression guard (no so…
jeremymanning Jul 6, 2026
06dfbff
fix(animate): 3D scene artists unclipped in all animation paths (axes…
jeremymanning Jul 6, 2026
1487435
docs: regenerate animated gallery media (axes-box slicing fix)
jeremymanning Jul 6, 2026
91d3fab
docs: evidence images rebuilt from CURRENT media at worst-angle frames
jeremymanning Jul 6, 2026
224b56f
feat(plot): multibyte character support -- auto font detection + font…
jeremymanning Jul 7, 2026
dfb2529
feat(plot): multibyte support for the plotly backend + CI font provis…
jeremymanning Jul 7, 2026
2656825
feat(plotly): labels= point annotations (parity with matplotlib; GH #…
jeremymanning Jul 7, 2026
28fb7e7
fix(tests): use Unicode noncharacters for the no-covering-font path (…
jeremymanning Jul 7, 2026
3148856
fix(fonts): exclude universal-fallback/placeholder fonts from coverag…
jeremymanning Jul 7, 2026
b87e635
fix(colorbar): discrete segments read in legend order (GH #100 follow…
jeremymanning Jul 7, 2026
bf33a54
test: procrustes non-default-parameter coverage + weak-assert audit f…
jeremymanning Jul 7, 2026
029ed07
fix: use isinstance for type checks throughout (GH #209)
jeremymanning Jul 7, 2026
2b76d4e
fix(plot): smooth marker+line styles like line-only styles (GH #141)
jeremymanning Jul 7, 2026
966abe3
feat(plot): resample= kwarg wiring hyp.manip Resample into the plot p…
jeremymanning Jul 7, 2026
715f055
feat(plot): arbitrary mpl kwargs passthrough + strict list-length val…
jeremymanning Jul 7, 2026
4e1a09a
notes: mark issue triage as executed (audit closed 45+13 issues, migr…
jeremymanning Jul 7, 2026
48e9d8f
notes: issue-audit session log
jeremymanning Jul 7, 2026
b11285b
plan: round 17 — address all 20 non-deferred open issues (API unifica…
jeremymanning Jul 7, 2026
b8ac8fe
feat(core): add Pipeline class + build_pipeline; unpack_model legacy …
jeremymanning Jul 7, 2026
1847c0f
fix(core): restore ValueError for wrong-type instances in unpack_model
jeremymanning Jul 7, 2026
33fac24
feat(reduce): migrate reduce/ to the 1.0 pattern + mixture models (#174)
jeremymanning Jul 7, 2026
1acd585
fix(reduce): warn on ndims mismatch for fitted-Reducer reuse; test ba…
jeremymanning Jul 7, 2026
ab8b6d2
feat(cluster): migrate cluster/ to the 1.0 pattern (round17 Task 3)
jeremymanning Jul 7, 2026
0c471ba
refactor(cluster): point reduce's mixture imports at cluster.common; …
jeremymanning Jul 7, 2026
084b5a6
feat(align): export the 1.0 align dispatcher; fix Aligner.transform t…
jeremymanning Jul 7, 2026
2b8377e
fix(align): SRM family transform() reused fit-time index (GH #227)
jeremymanning Jul 7, 2026
b4fd527
fix(align): coerce raw-array new_data to DataFrame(s) in Aligner.tran…
jeremymanning Jul 7, 2026
77749d6
feat(manip): manip list-chaining via Pipeline + return_model + Smooth…
jeremymanning Jul 7, 2026
783dd98
fix(manip): Resample.transform uses new data's values; Smooth kernel=…
jeremymanning Jul 7, 2026
b49e70c
feat(core,tools,plot): cross-module kwargs on analyze/normalize/plot …
jeremymanning Jul 7, 2026
db211e4
fix(plot,tools): thread n_clusters into bundle pipeline; honor impute…
jeremymanning Jul 7, 2026
b513bca
feat(plot): label_alpha=, xlabel=/ylabel=/zlabel=, animate= dict form…
jeremymanning Jul 7, 2026
ad347cc
feat(plot): animate='window' + focused= + duration= verification (rou…
jeremymanning Jul 7, 2026
e02e7eb
feat(plot): 2D animations, both backends (round17 #9, GH #123)
jeremymanning Jul 7, 2026
29f225f
feat(reduce): add torch-backed autoencoder reducers (GH #162)
jeremymanning Jul 7, 2026
8dad36a
feat(io): add scikit-learn and seaborn named datasets to hyp.load (#273)
jeremymanning Jul 7, 2026
161b870
docs(io): warn that sklearn/seaborn dataset names shadow same-named l…
jeremymanning Jul 7, 2026
cf43204
feat(io): add fivethirtyeight/ and kaggle/ explicit-prefix loaders (#…
jeremymanning Jul 7, 2026
3158605
fix(io): scope kagglehub skip to kaggle tests, dedupe kaggle table ke…
jeremymanning Jul 7, 2026
ac9421a
feat(io): add hyp.io.lsl_stream for LSL input (GH #130)
jeremymanning Jul 7, 2026
f01df42
fix(io): bounded per-sample timeout + inlet cleanup for lsl_stream
jeremymanning Jul 7, 2026
5f42880
feat(text2mat): gensim vectorizer=/semantic= wrappers, sklearn->gensi…
jeremymanning Jul 7, 2026
2fef66c
test(gensim): cover all-OOV zero-vector fallback; document Doc2Vec in…
jeremymanning Jul 7, 2026
9913817
feat(evidence): pieman story-trajectories demo end-to-end + jumps evi…
jeremymanning Jul 7, 2026
d43649d
fix(evidence): story-trajectories early frame -- require fully-popula…
jeremymanning Jul 7, 2026
ab39732
fix(io,ci): authenticate fivethirtyeight GitHub API calls to avoid CI…
jeremymanning Jul 7, 2026
357d1f9
docs: add numpydoc docstrings to every public def/class outside _exte…
jeremymanning Jul 7, 2026
6c3a373
docs: comprehensive Sphinx docs pass -- api.rst coverage, pipeline fl…
jeremymanning Jul 7, 2026
3bb956d
docs(examples): make datasets-tour resilient to network hiccups at ga…
jeremymanning Jul 7, 2026
777b58e
docs(readme): regenerate all media with 1.0 code, fix badges + stale …
jeremymanning Jul 7, 2026
8c40499
fix(io): fetch 538 CSVs via authenticated GitHub API to avoid raw.git…
jeremymanning Jul 7, 2026
6201e42
docs: fix stale 1.0 architecture claims in CLAUDE.md
jeremymanning Jul 8, 2026
6397a24
docs: retire legacy 0.x tutorial rst duplicates and DataGeometry tuto…
jeremymanning Jul 8, 2026
5403530
fix(core,normalize): Normalizer.transform reuse on new data + manip k…
jeremymanning Jul 8, 2026
3c5c816
docs(readme): fix mat2colors path, document missing 1.0 features and …
jeremymanning Jul 8, 2026
2badcf9
feat(manip): make ZScore/Normalize invertible so Pipeline.inverse_tra…
jeremymanning Jul 8, 2026
7e42095
fix(text2mat): skip topic-model semantic on embedding vectorizers ins…
jeremymanning Jul 8, 2026
376e1d9
docs(api): correct docstring inaccuracies surfaced by the QC audit (A…
jeremymanning Jul 8, 2026
724ad5f
docs: fix tutorials.rst title-underline lengths (clears 8 sphinx warn…
jeremymanning Jul 8, 2026
778c49c
docs(qc): triage notes + evidence for QC-notes fix effort (no code ch…
jeremymanning Jul 8, 2026
901f3e2
fix(deps): promote pykalman+statsmodels to core; pin plotly>=6.1.1/ka…
jeremymanning Jul 9, 2026
8e07a59
fix(deps): correct deps red-team defects (ARIMA msg, deepdish numpy2,…
jeremymanning Jul 9, 2026
d9024ba
fix(models): make every returned model honor the sklearn estimator pr…
jeremymanning Jul 9, 2026
8d32445
fix(dispatch): reuse a fitted Pipeline/wrapper handed back as a stage…
jeremymanning Jul 9, 2026
77d1e46
feat(api): predict 'GP' alias + describe() despine/plotly backend
jeremymanning Jul 9, 2026
621555b
fix(reuse): positional manip keying + clear plot() error (reuse red-t…
jeremymanning Jul 9, 2026
d458a5b
fix(plot): matrix-hue blending, surface honors hue, color_reduce= (QC…
jeremymanning Jul 9, 2026
5d3ecd7
feat(plot): names= dataset legend, fix notebook double-display, color…
jeremymanning Jul 9, 2026
f5dfebe
feat(plot): HyperAnimation return + chemtrails/precog/bullettime anim…
jeremymanning Jul 9, 2026
6472172
docs(gallery): story-trajectory animated gif thumbnail + tutorial-set…
jeremymanning Jul 9, 2026
5ad45b7
docs(notes): update QC-notes resume ledger through animation A+B + st…
jeremymanning Jul 9, 2026
23d0c9a
fix(plot): animate + per-observation hue no longer crashes (QC animat…
jeremymanning Jul 9, 2026
dc46a3a
docs(notes): QC-fix evidence screenshots for PR comments
jeremymanning Jul 9, 2026
edf6049
fix(backend): set_interactive_backend('plotly') selects the render ba…
jeremymanning Jul 9, 2026
66675cb
fix(reduce): honor ndims in the canonical dict spec; stable return ty…
jeremymanning Jul 9, 2026
7d71975
fix(input): robust coercion + clear errors for common inputs (release…
jeremymanning Jul 9, 2026
ca13d05
fix(manip/impute): PPCA preserves observed values; robust imputers/ZS…
jeremymanning Jul 9, 2026
3072545
fix(core): analyze returns data not labels; robust Pipeline/build_pip…
jeremymanning Jul 9, 2026
00607d2
fix(align): support datasets with different column counts; warn on ro…
jeremymanning Jul 9, 2026
176fbd7
fix(animation): save all formats; validate duration/frame_rate; fix m…
jeremymanning Jul 9, 2026
be0dcb5
fix(edge): empty-input error, predict-horizon validation, streaming k…
jeremymanning Jul 9, 2026
4fc2e1b
fix(impute): PPCA densifies dropped columns; single-col + reuse clear…
jeremymanning Jul 9, 2026
9d5ce9d
fix(cluster): label recovery works for hard clusterers; clarify analy…
jeremymanning Jul 9, 2026
111775a
fix(input): align dict-form unknown model, 0-d array, scalar hue, PPC…
jeremymanning Jul 9, 2026
a81c7a9
fix(predict/backend): numpy-bool/0-d horizon, DatetimeIndex raise, ca…
jeremymanning Jul 9, 2026
ffc3ca4
docs(notes): release-hardening PR evidence (screenshots + numeric res…
jeremymanning Jul 9, 2026
8e6ed68
fix(surface): color each hull vertex by a distance-weighted blend of …
jeremymanning Jul 9, 2026
b84f827
fix(docs): register story-trajectories gif thumbnail in post_build
jeremymanning Jul 9, 2026
afd7c07
fix(surface): an explicit surface color= wins over hue per-vertex col…
jeremymanning Jul 9, 2026
5972fb4
fix(docs): animate_surface_morph gif thumbnail + guard against frozen…
jeremymanning Jul 9, 2026
94c03d0
docs(notes): evidence for surface hue-per-vertex + story/surface_morp…
jeremymanning Jul 9, 2026
849d97c
docs(notes): finalize PR comment with 1466-pass suite result
jeremymanning Jul 9, 2026
7cc88ff
fix(animate): fractional duration no longer crashes spin/serial anima…
jeremymanning Jul 10, 2026
bd04856
feat(story): high-quality story-trajectories animation (align in low-…
jeremymanning Jul 10, 2026
8456494
docs(notes): story-animation PR evidence (new gif + honest metrics)
jeremymanning Jul 10, 2026
7987f3e
fix(story): align in the 100-hub space (not over-reduced), window style
jeremymanning Jul 10, 2026
cc42822
fix(pipeline): a no-op reduce stage is fitted, keeping return_model p…
jeremymanning Jul 10, 2026
52bcff8
fix(animate): per-point labels track their datapoint's window instead…
jeremymanning Jul 10, 2026
26232a6
feat(api): top-level random_state for reproducible reduce/cluster/ana…
jeremymanning Jul 10, 2026
aaf12b9
fix(animate): window per-point labels in serial/2-D/morph animations too
jeremymanning Jul 10, 2026
a87aa4a
docs(story): cleaner window animation (shorter trail, translucent thi…
jeremymanning Jul 10, 2026
5a4fe93
docs(story): match reference render (opaque bold lines) + verified di…
jeremymanning Jul 10, 2026
fdb5292
docs(story): husl palette to match the reference's tempered hues
jeremymanning Jul 10, 2026
6d9a596
docs(notes): finalize session PR comment + husl story gif evidence
jeremymanning Jul 10, 2026
7507a23
fix(plot): accept nested per-dataset hue (list-of-lists) again
jeremymanning Jul 10, 2026
e34a51d
docs(notes): gallery-examples + tutorials audit follow-up comment
jeremymanning Jul 10, 2026
571e331
chore: remove dev-only QC review scaffolding before merging to dev
jeremymanning Jul 10, 2026
eec6538
Merge pull request #280 from ContextLab/fix/qc-notes-2026-07
jeremymanning Jul 10, 2026
e0f4e33
fix(io): retry transient GitHub-API gateway errors in the 538 loader
jeremymanning Jul 10, 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
  •  
  •  
  •  
69 changes: 66 additions & 3 deletions .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 @@ -45,7 +49,11 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y ffmpeg
# fonts-noto-cjk (GH #205): ubuntu-latest ships no CJK-covering font
# at all, so tests/test_multibyte.py's `requires_covering_font`
# skipif would silently skip every CJK-dependent test on this OS.
sudo apt-get install -y ffmpeg fonts-noto-cjk
fc-cache -f

- name: Install system dependencies (macOS)
if: matrix.os == 'macos-latest'
Expand All @@ -59,20 +67,75 @@ jobs:
continue-on-error: true

- name: Install package with dev dependencies
# GH #130 (hyp.io.lsl_stream, tests/test_lsl_streaming.py): pylsl is
# in the [dev] extra (pyproject.toml) with NO separate native liblsl
# install step on any of the three platforms below -- investigated
# during Task 13's implementation, pylsl>=1.16's wheels BUNDLE the
# native liblsl library for every platform this matrix runs on:
# - ubuntu-latest (x86_64): manylinux_2_35_x86_64 wheel -> ships
# pylsl/lib/liblsl.so (ubuntu-latest's glibc satisfies 2.35+)
# - macos-latest (arm64/x86_64): macosx_11_0_universal2 wheel ->
# ships pylsl/lib/liblsl.dylib; verified working end-to-end
# locally (real in-process StreamOutlet -> StreamInlet round trip)
# - windows-latest (x86_64): win_amd64 wheel -> ships
# pylsl/lib/lsl.dll
# so all three CI platforms are "provisioned" and none is excluded;
# tests/test_lsl_streaming.py::test_ci_has_pylsl fails the build (not
# skip) if pylsl is ever unimportable here, e.g. if a future pylsl
# release drops the bundled binary for one of these wheel tags.
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
# [torch] (also pulled in transitively by [dev]) is installed
# explicitly too so a future change to the dev extra can't
# silently drop torch coverage of the six autoencoder reducers
# (GH #162, tests/test_autoencoders.py). torch>=2.0 ships CPU
# wheels for all three CI platforms/Python versions here.
pip install -e ".[dev,torch]"

- name: Rebuild matplotlib font cache (Ubuntu only)
# GH #205: matplotlib scans installed fonts once and caches the
# result (~/.cache/matplotlib/fontlist-*.json). On ubuntu-latest
# runners that cache is built (by whatever process first imports
# matplotlib.font_manager -- here, `pip install`'s dependency
# resolution/build step, or a previous cached run) BEFORE
# fonts-noto-cjk is installed above, so `find_covering_font`
# (hypertools/plot/fonts.py) would scan a stale font list missing
# every Noto Sans CJK file and skip every CJK-dependent test in
# tests/test_multibyte.py. Force one rebuild here (expensive -- do
# it once per job, not from inside fonts.py on every call).
if: matrix.os == 'ubuntu-latest'
run: |
python -c "import matplotlib.font_manager as fm; fm._load_fontmanager(try_read_cache=False)"

- name: Run pytest
env:
MPLBACKEND: Agg
# Authenticate the fivethirtyeight loader's GitHub API listing calls
# (tests/test_load_538_kaggle.py). The default GITHUB_TOKEN raises the
# REST API quota from 60 to 5000 requests/hour, so the ~12 concurrent
# matrix jobs sharing a runner IP pool don't exhaust the shared
# unauthenticated limit (403 rate-limit failures). See
# hypertools/io/sources.py::_github_api_headers.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
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
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
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:
MPLBACKEND: Agg
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pytest --cov=hypertools --cov-report=xml --cov-report=term-missing

Expand Down
59 changes: 42 additions & 17 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

HyperTools is a Python library for visualizing and manipulating high-dimensional data. It provides a unified interface for dimensionality reduction, data alignment, clustering, and visualization, built on top of matplotlib, scikit-learn, and seaborn.
HyperTools is a Python library for visualizing and manipulating high-dimensional data. It provides a unified interface for dimensionality reduction, data alignment, clustering, and visualization, built on top of matplotlib, plotly (interactive backend), scikit-learn, seaborn, and pydata-wrangler (core data-wrangling).

## Key Commands

### Testing
- `pytest` - Run all tests from the hypertools/ directory
- `pytest` - Run all tests (run from the repo root; `pyproject.toml` sets `testpaths = ["tests"]`)
- `pytest tests/test_<module>.py` - Run tests for a specific module
- `pytest tests/test_<module>.py::test_<function>` - Run a specific test function

### Development Setup
- `pip install -e ".[dev]"` - Install in development mode with test dependencies (all deps declared in pyproject.toml)
- `pip install -e ".[dev]"` - Install in development mode with test/dev dependencies. `[dev]` does NOT pull in every optional extra: `text` (pydata-wrangler[hf], HF text embeddings) and `predict-hf` (chronos-forecasting) are left out, and their code paths are `importorskip`-guarded in tests.
- `pip install -r docs/doc_requirements.txt` - Install documentation dependencies

### Documentation
Expand All @@ -26,36 +26,61 @@ HyperTools is a Python library for visualizing and manipulating high-dimensional
### Core Components

**DataGeometry Class** (`hypertools/datageometry.py`)
- Central data container that holds raw data, transformed data, and transformation parameters
- Stores matplotlib figure/axes handles and animation objects
- Contains normalization, reduction, and alignment model parameters
- INTERNAL, unpickle-only legacy shell (its own docstring: "not part of the public API"); not used by any current API function
- Kept solely so `hypertools.load()` can unpickle hosted example-dataset geo files (created by hypertools < 1.0) and extract their raw data via `get_data()`
- In 1.0, `plot()` returns a matplotlib `Figure` and `load()` returns raw data -- no `DataGeometry` is ever constructed or returned to users

**Main API Functions** (`hypertools/__init__.py`)
- `plot()` - Primary visualization function
- `analyze()` - Data analysis and dimensionality reduction
- `analyze()` - Classic manip -> normalize -> reduce -> align -> cluster pipeline dispatcher
- `reduce()` - Dimensionality reduction utilities
- `align()` - Data alignment across datasets
- `normalize()` - Data normalization
- `describe()` - Data description and summary
- `cluster()` - Clustering functionality
- `manip()` - Manipulator dispatcher (Normalize/ZScore/Smooth/Resample, etc.)
- `predict()` - Timeseries forecasting (ARIMA, Kalman, GP, autoregression, Chronos, etc.)
- `impute()` - Missing-data imputation (PPCA, Kalman, sklearn imputers)
- `load()` - Data loading utilities
- `save()` - Save data/results to disk
- `apply_model()` - Apply an arbitrary sklearn-API model to data
- `Pipeline` - Class for chaining/reusing manip/reduce/align/cluster stages
- `set_interactive_backend()` - Switch the plotting backend (matplotlib/plotly)
- `io` submodule - I/O helpers, including `io.lsl_stream()` for Lab Streaming Layer input

**Tools Module** (`hypertools/tools/`)
- `align.py` - Hyperalignment and Procrustes alignment
- `reduce.py` - Dimensionality reduction (PCA, t-SNE, UMAP, etc.)
- `normalize.py` - Data normalization methods
- `cluster.py` - K-means and other clustering algorithms
- `align.py` - Classic array/mode `align()` API; thin compatibility wrapper over `hypertools/align/`
- `analyze.py` - `analyze()` pipeline dispatcher
- `normalize.py` - `normalize()` (z-scoring) with cross-module stage kwargs
- `format_data.py` - Data preprocessing and formatting
- `text2mat.py` - Text-to-matrix conversion
- `df2mat.py` - DataFrame-to-matrix conversion
- `load.py` - Data loading from various sources
- `gensim_models.py` - sklearn-API wrappers around gensim topic/embedding models
- `missing_inds.py` - Missing data handling
- `procrustes.py` - Procrustes analysis

The dev-1.0 refactor moved several tools into their own top-level subpackages (each a folder with a main module plus helpers):
- `hypertools/reduce/` - Dimensionality reduction (`reduce.py`, `describe.py`, `autoencoders.py`, `common.py`)
- `hypertools/cluster/` - Clustering (`cluster.py`, `common.py`)
- `hypertools/align/` - Alignment (`align.py`, `hyperalign.py`, `procrustes.py`, `srm.py`, `null.py`, `common.py`)
- `hypertools/manip/` - Manipulators (`manip.py`, `normalize.py`, `zscore.py`, `smooth.py`, `resample.py`, `common.py`)
- `hypertools/io/` - Loading/saving/streaming (`load.py`, `save.py`, `sources.py`, `streaming.py`, `lsl.py`)
- `hypertools/predict/` - Forecasting models (`predict.py`, `arima.py`, `autoreg.py`, `gp.py`, `kalman.py`, `laplace.py`, `chronos.py`, `common.py`)
- `hypertools/impute/` - Imputation models (`impute.py`, `ppca.py`, `kalman.py`, `sklearn_imputers.py`, `common.py`)
- `hypertools/core/` - Shared config/exceptions and `apply_model()`/`Pipeline` (`configurator.py`, `exceptions.py`, `model.py`, `pipeline.py`, `shared.py`)

**Plot Module** (`hypertools/plot/`)
- `plot.py` - Main plotting interface and logic
- `backend.py` - matplotlib backend configuration
- `draw.py` - Low-level drawing functions
- `backend.py` - Backend selection (`set_interactive_backend()`)
- `matplotlib_backend.py` - Low-level matplotlib drawing (`draw.py` is now a 3-line compatibility shim over this)
- `plotly_backend.py` - Low-level plotly drawing (interactive backend)
- `interactive.py` - Interactive-mode helpers
- `animate.py` - Animation support
- `colors.py` - Color handling
- `density.py` / `surface.py` - Density and iso-surface rendering
- `morph.py` / `trails.py` - Morph and trail effects
- `meshutil.py` - Mesh utilities
- `multiindex.py` - Pandas MultiIndex handling
- `fonts.py` - Font handling

**External Dependencies** (`hypertools/_externals/`)
- `ppca.py` - Probabilistic Principal Component Analysis
Expand All @@ -82,10 +107,10 @@ HyperTools is a Python library for visualizing and manipulating high-dimensional

- The package follows a functional programming style with separate modules for each operation
- All major functions are designed to work with multiple input formats
- The DataGeometry class serves as the central data container and state manager
- `plot()` returns a matplotlib `Figure`; `load()` returns raw data -- there is no central state-container object in 1.0 (`DataGeometry` is an internal unpickle-only legacy shell; see above)
- Tests are located in `tests/` directory and follow pytest conventions
- Documentation is built with Sphinx and uses example galleries
- The codebase maintains compatibility with Python 3.9+
- The codebase requires Python 3.10+ (`requires-python = ">=3.10"`)

## Testing Strategy

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.
Loading
Loading