diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2f919520..808a8e92 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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 ] @@ -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: @@ -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: diff --git a/dev/animation_demo.gif b/dev/animation_demo.gif index e7295143..ad894243 100644 Binary files a/dev/animation_demo.gif and b/dev/animation_demo.gif differ diff --git a/dev/hypertools_2.0_dev.ipynb b/dev/hypertools_1.0_dev.ipynb similarity index 95% rename from dev/hypertools_2.0_dev.ipynb rename to dev/hypertools_1.0_dev.ipynb index d86326d4..a3f7f437 100644 --- a/dev/hypertools_2.0_dev.ipynb +++ b/dev/hypertools_1.0_dev.ipynb @@ -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", @@ -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)" @@ -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." ] }, { @@ -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", diff --git a/dev/hypertools_2.0_dev_executed.ipynb b/dev/hypertools_1.0_dev_executed.ipynb similarity index 99% rename from dev/hypertools_2.0_dev_executed.ipynb rename to dev/hypertools_1.0_dev_executed.ipynb index 6136da57..4b3b18cc 100644 --- a/dev/hypertools_2.0_dev_executed.ipynb +++ b/dev/hypertools_1.0_dev_executed.ipynb @@ -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", @@ -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" ] } @@ -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)" @@ -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." ] }, { @@ -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." ] @@ -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=) ---" ] }, diff --git a/dev/plotly_spin_demo.gif b/dev/plotly_spin_demo.gif index f10acdc8..e1e0030f 100644 Binary files a/dev/plotly_spin_demo.gif and b/dev/plotly_spin_demo.gif differ diff --git a/docs/api.rst b/docs/api.rst index 540a2524..f2138c9c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -7,16 +7,6 @@ API reference ============= -.. _plot_api: - -DataGeometry class ------------------- - -.. autosummary:: - :toctree: - - hypertools.DataGeometry - Load ------------------ @@ -73,6 +63,22 @@ Cluster hypertools.cluster +Predict +------------------ + +.. autosummary:: + :toctree: + + hypertools.predict + +Impute +------------------ + +.. autosummary:: + :toctree: + + hypertools.impute + Apply model ------------------ @@ -99,7 +105,7 @@ Tools .. autosummary:: :toctree: - hypertools.tools.procrustes + hypertools.align.procrustes .. autosummary:: :toctree: diff --git a/docs/auto_examples/analyze.codeobj.json b/docs/auto_examples/analyze.codeobj.json index 8a8b1813..6e82e8be 100644 --- a/docs/auto_examples/analyze.codeobj.json +++ b/docs/auto_examples/analyze.codeobj.json @@ -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, diff --git a/docs/auto_examples/analyze.ipynb b/docs/auto_examples/analyze.ipynb index edbe1f22..322647a6 100644 --- a/docs/auto_examples/analyze.ipynb +++ b/docs/auto_examples/analyze.ipynb @@ -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 +} \ No newline at end of file diff --git a/docs/auto_examples/analyze.py b/docs/auto_examples/analyze.py index 5035215e..16dce767 100644 --- a/docs/auto_examples/analyze.py +++ b/docs/auto_examples/analyze.py @@ -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, diff --git a/docs/auto_examples/analyze.py.md5 b/docs/auto_examples/analyze.py.md5 index d597194d..28b0f1c9 100644 --- a/docs/auto_examples/analyze.py.md5 +++ b/docs/auto_examples/analyze.py.md5 @@ -1 +1 @@ -b188d6db61e339db0651634314ffdc5a \ No newline at end of file +68992cc2797469b2fefb43fcf35a16d6 \ No newline at end of file diff --git a/docs/auto_examples/analyze.rst b/docs/auto_examples/analyze.rst index b2d1de99..e410fb59 100644 --- a/docs/auto_examples/analyze.rst +++ b/docs/auto_examples/analyze.rst @@ -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 @@ -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, @@ -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: diff --git a/docs/auto_examples/analyze.zip b/docs/auto_examples/analyze.zip index 8170a90b..29d2ca32 100644 Binary files a/docs/auto_examples/analyze.zip and b/docs/auto_examples/analyze.zip differ diff --git a/docs/auto_examples/animate.codeobj.json b/docs/auto_examples/animate.codeobj.json index 1503c46f..dc560397 100644 --- a/docs/auto_examples/animate.codeobj.json +++ b/docs/auto_examples/animate.codeobj.json @@ -15,71 +15,48 @@ "name": "FuncAnimation" } ], - "ani_geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "ani_geo.line_ani": [ + "fig": [ { "is_class": false, "is_explicit": false, - "module": "matplotlib.animation", - "module_short": "matplotlib.animation", - "name": "FuncAnimation" + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" }, { "is_class": false, "is_explicit": false, "module": "matplotlib", "module_short": "matplotlib", - "name": "FuncAnimation" + "name": "Figure" } ], - "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.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -92,7 +69,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/animate.ipynb b/docs/auto_examples/animate.ipynb index dc801ce1..0a1c857e 100644 --- a/docs/auto_examples/animate.ipynb +++ b/docs/auto_examples/animate.ipynb @@ -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# Animated plots\n\nTimeseries plots can be animated by simply passing `animate=True` when\ncalling hyp.plot.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_animate_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ndata = hyp.load('weights_avg')\n\n# plot\nfig, ani = hyp.plot(data, animate=True, legend=['first', 'second'])" + ] + } + ], + "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# Animated plots\n\nTimeseries plots can be animated by simply passing `animate=True` to the geo (\nor when calling hyp.plot).\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_animate_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ngeo = hyp.load('weights_avg')\n\n# plot\nani_geo = geo.plot(animate=True, legend=['first', 'second'])\nani = ani_geo.line_ani # the underlying matplotlib FuncAnimation" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/animate.py b/docs/auto_examples/animate.py index d96ee275..03f56aee 100644 --- a/docs/auto_examples/animate.py +++ b/docs/auto_examples/animate.py @@ -4,8 +4,8 @@ Animated plots ============================= -Timeseries plots can be animated by simply passing `animate=True` to the geo ( -or when calling hyp.plot). +Timeseries plots can be animated by simply passing `animate=True` when +calling hyp.plot. """ # sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_animate_thumb.gif' @@ -17,8 +17,7 @@ import hypertools as hyp # load example data -geo = hyp.load('weights_avg') +data = hyp.load('weights_avg') # plot -ani_geo = geo.plot(animate=True, legend=['first', 'second']) -ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation +fig, ani = hyp.plot(data, animate=True, legend=['first', 'second']) diff --git a/docs/auto_examples/animate.py.md5 b/docs/auto_examples/animate.py.md5 index 7aa85fb3..3430e3d5 100644 --- a/docs/auto_examples/animate.py.md5 +++ b/docs/auto_examples/animate.py.md5 @@ -1 +1 @@ -aa5bc3593032f96dd28767c310605c61 \ No newline at end of file +99485eb15977b55d11efb75e13f17ec1 \ No newline at end of file diff --git a/docs/auto_examples/animate.rst b/docs/auto_examples/animate.rst index 287f87ed..4391ac66 100644 --- a/docs/auto_examples/animate.rst +++ b/docs/auto_examples/animate.rst @@ -22,17 +22,17 @@ Animated plots ============================= -Timeseries plots can be animated by simply passing `animate=True` to the geo ( -or when calling hyp.plot). +Timeseries plots can be animated by simply passing `animate=True` when +calling hyp.plot. -.. GENERATED FROM PYTHON SOURCE LINES 10-25 +.. GENERATED FROM PYTHON SOURCE LINES 10-24 .. video:: /auto_examples/images/sphx_glr_animate_001.mp4 :class: sphx-glr-single-img :height: 480 - :width: 640 + :width: 683 :autoplay: @@ -52,16 +52,15 @@ or when calling hyp.plot). import hypertools as hyp # load example data - geo = hyp.load('weights_avg') + data = hyp.load('weights_avg') # plot - ani_geo = geo.plot(animate=True, legend=['first', 'second']) - ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation + fig, ani = hyp.plot(data, animate=True, legend=['first', 'second']) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 10.973 seconds) + **Total running time of the script:** (0 minutes 12.906 seconds) .. _sphx_glr_download_auto_examples_animate.py: diff --git a/docs/auto_examples/animate.zip b/docs/auto_examples/animate.zip index 810084d2..ed312771 100644 Binary files a/docs/auto_examples/animate.zip and b/docs/auto_examples/animate.zip differ diff --git a/docs/auto_examples/animate_MDS.codeobj.json b/docs/auto_examples/animate_MDS.codeobj.json index 1503c46f..dc560397 100644 --- a/docs/auto_examples/animate_MDS.codeobj.json +++ b/docs/auto_examples/animate_MDS.codeobj.json @@ -15,71 +15,48 @@ "name": "FuncAnimation" } ], - "ani_geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "ani_geo.line_ani": [ + "fig": [ { "is_class": false, "is_explicit": false, - "module": "matplotlib.animation", - "module_short": "matplotlib.animation", - "name": "FuncAnimation" + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" }, { "is_class": false, "is_explicit": false, "module": "matplotlib", "module_short": "matplotlib", - "name": "FuncAnimation" + "name": "Figure" } ], - "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.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -92,7 +69,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/animate_MDS.ipynb b/docs/auto_examples/animate_MDS.ipynb index e248b6b3..a2f77c44 100644 --- a/docs/auto_examples/animate_MDS.ipynb +++ b/docs/auto_examples/animate_MDS.ipynb @@ -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# Animated trajectory plotted with multidimensional scaling\n\nThis is a trajectory of brain data plotted in 3D with multidimensional scaling.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_animate_MDS_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import hypertools\nimport hypertools as hyp\n\n# load the data\ndata = hyp.load('weights_avg')\n\n# plot\nfig, ani = hyp.plot(data, animate=True, reduce='MDS')" + ] + } + ], + "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# Animated trajectory plotted with multidimensional scaling\n\nThis is a trajectory of brain data plotted in 3D with multidimensional scaling.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_animate_MDS_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import hypertools\nimport hypertools as hyp\n\n# load the geo\ngeo = hyp.load('weights_avg')\n\n# plot\nani_geo = geo.plot(animate=True, reduce='MDS')\nani = ani_geo.line_ani # the underlying matplotlib FuncAnimation" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/animate_MDS.py b/docs/auto_examples/animate_MDS.py index 78023abd..a623219a 100644 --- a/docs/auto_examples/animate_MDS.py +++ b/docs/auto_examples/animate_MDS.py @@ -15,9 +15,8 @@ # import hypertools import hypertools as hyp -# load the geo -geo = hyp.load('weights_avg') +# load the data +data = hyp.load('weights_avg') # plot -ani_geo = geo.plot(animate=True, reduce='MDS') -ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation +fig, ani = hyp.plot(data, animate=True, reduce='MDS') diff --git a/docs/auto_examples/animate_MDS.py.md5 b/docs/auto_examples/animate_MDS.py.md5 index 3db2cff8..912f8e51 100644 --- a/docs/auto_examples/animate_MDS.py.md5 +++ b/docs/auto_examples/animate_MDS.py.md5 @@ -1 +1 @@ -8a5b42387ccdae7c2ab5fbd5ac602a11 \ No newline at end of file +e04bece23e3e8a3f7a5b77e9a9e18979 \ No newline at end of file diff --git a/docs/auto_examples/animate_MDS.rst b/docs/auto_examples/animate_MDS.rst index 4dad2555..c205aaec 100644 --- a/docs/auto_examples/animate_MDS.rst +++ b/docs/auto_examples/animate_MDS.rst @@ -24,7 +24,7 @@ Animated trajectory plotted with multidimensional scaling This is a trajectory of brain data plotted in 3D with multidimensional scaling. -.. GENERATED FROM PYTHON SOURCE LINES 9-24 +.. GENERATED FROM PYTHON SOURCE LINES 9-23 @@ -63,17 +63,16 @@ This is a trajectory of brain data plotted in 3D with multidimensional scaling. # import hypertools import hypertools as hyp - # load the geo - geo = hyp.load('weights_avg') + # load the data + data = hyp.load('weights_avg') # plot - ani_geo = geo.plot(animate=True, reduce='MDS') - ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation + fig, ani = hyp.plot(data, animate=True, reduce='MDS') .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 7.567 seconds) + **Total running time of the script:** (0 minutes 5.847 seconds) .. _sphx_glr_download_auto_examples_animate_MDS.py: diff --git a/docs/auto_examples/animate_MDS.zip b/docs/auto_examples/animate_MDS.zip index 44f1a24b..cbe9daa8 100644 Binary files a/docs/auto_examples/animate_MDS.zip and b/docs/auto_examples/animate_MDS.zip differ diff --git a/docs/auto_examples/animate_plotly.ipynb b/docs/auto_examples/animate_plotly.ipynb index b722eac7..7c690288 100644 --- a/docs/auto_examples/animate_plotly.ipynb +++ b/docs/auto_examples/animate_plotly.ipynb @@ -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# Animated interactive plots (plotly backend)\n\nAnimations work on the plotly backend too: `animate=True` reveals\ntrajectories through a sliding time window and `animate='spin'` rotates the\ncamera, each with interactive play/pause controls in notebooks. Animations\non either backend export to `.gif`, animated `.png`, or `.mp4` -- the file\nextension picks the format.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\ndata = np.cumsum(np.random.default_rng(42).standard_normal((200, 8)),\n axis=0)\n\n# interactive animation (play/pause controls in notebooks)\nhyp.plot(data, animate=True, duration=30, backend='plotly')\n\n# export an animation: extension picks the format (.gif / .png / .mp4)\nhyp.plot(data, animate='spin', duration=30, backend='plotly',\n save_path='spin.gif', show=False)" + ] + } + ], + "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# Animated interactive plots (plotly backend)\n\nAnimations work on the plotly backend too: `animate=True` reveals\ntrajectories through a sliding time window and `animate='spin'` rotates the\ncamera, each with interactive play/pause controls in notebooks. Animations\non either backend export to `.gif`, animated `.png`, or `.mp4` -- the file\nextension picks the format.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\ndata = np.cumsum(np.random.default_rng(42).standard_normal((200, 8)),\n axis=0)\n\n# interactive animation (play/pause controls in notebooks)\nhyp.plot(data, animate=True, duration=30, backend='plotly')\n\n# export an animation: extension picks the format (.gif / .png / .mp4)\nhyp.plot(data, animate='spin', duration=30, backend='plotly',\n save_path='spin.gif', show=False)" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/animate_plotly.rst b/docs/auto_examples/animate_plotly.rst index 70a49751..07b05327 100644 --- a/docs/auto_examples/animate_plotly.rst +++ b/docs/auto_examples/animate_plotly.rst @@ -36,21 +36,19 @@ extension picks the format. :file: images/sphx_glr_animate_plotly_001.html -.. rst-class:: sphx-glr-script-out - - .. code-block:: none - - Resorting to unclean kill browser. - Resorting to unclean kill browser. - Resorting to unclean kill browser. - Resorting to unclean kill browser. - - - - +.. raw:: html -| +
+
+
+
+
+
.. code-block:: Python @@ -74,7 +72,7 @@ extension picks the format. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (47 minutes 29.943 seconds) + **Total running time of the script:** (46 minutes 56.795 seconds) .. _sphx_glr_download_auto_examples_animate_plotly.py: diff --git a/docs/auto_examples/animate_plotly.zip b/docs/auto_examples/animate_plotly.zip index 3f446d4f..0d2468ac 100644 Binary files a/docs/auto_examples/animate_plotly.zip and b/docs/auto_examples/animate_plotly.zip differ diff --git a/docs/auto_examples/animate_spin.codeobj.json b/docs/auto_examples/animate_spin.codeobj.json index 1503c46f..dc560397 100644 --- a/docs/auto_examples/animate_spin.codeobj.json +++ b/docs/auto_examples/animate_spin.codeobj.json @@ -15,71 +15,48 @@ "name": "FuncAnimation" } ], - "ani_geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "ani_geo.line_ani": [ + "fig": [ { "is_class": false, "is_explicit": false, - "module": "matplotlib.animation", - "module_short": "matplotlib.animation", - "name": "FuncAnimation" + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" }, { "is_class": false, "is_explicit": false, "module": "matplotlib", "module_short": "matplotlib", - "name": "FuncAnimation" + "name": "Figure" } ], - "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.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -92,7 +69,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/animate_spin.ipynb b/docs/auto_examples/animate_spin.ipynb index f7714315..4b4749a7 100644 --- a/docs/auto_examples/animate_spin.ipynb +++ b/docs/auto_examples/animate_spin.ipynb @@ -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# Create a rotating static plot\n\nIn addition to plotting dynamic timeseries data, the spin feature can be used to\nvisualize static data in an animated rotating plot.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_animate_spin_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import hypertools\nimport hypertools as hyp\n\n# load the data\ndata = hyp.load('weights_sample')\n\n# plot\nfig, ani = hyp.plot(data, fmt='.', animate='spin')" + ] + } + ], + "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# Create a rotating static plot\n\nIn addition to plotting dynamic timeseries data, the spin feature can be used to\nvisualize static data in an animated rotating plot.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_animate_spin_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import hypertools\nimport hypertools as hyp\n\n# load the geo\ngeo = hyp.load('weights_sample')\n\n# plot\nani_geo = geo.plot(fmt='.', animate='spin')\nani = ani_geo.line_ani # the underlying matplotlib FuncAnimation" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/animate_spin.py b/docs/auto_examples/animate_spin.py index 0d59889d..9ce8b709 100644 --- a/docs/auto_examples/animate_spin.py +++ b/docs/auto_examples/animate_spin.py @@ -16,9 +16,8 @@ # import hypertools import hypertools as hyp -# load the geo -geo = hyp.load('weights_sample') +# load the data +data = hyp.load('weights_sample') # plot -ani_geo = geo.plot(fmt='.', animate='spin') -ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation +fig, ani = hyp.plot(data, fmt='.', animate='spin') diff --git a/docs/auto_examples/animate_spin.py.md5 b/docs/auto_examples/animate_spin.py.md5 index 35783d81..790aa3e6 100644 --- a/docs/auto_examples/animate_spin.py.md5 +++ b/docs/auto_examples/animate_spin.py.md5 @@ -1 +1 @@ -d66b865e2f33dee0ce7852e3a978aa29 \ No newline at end of file +60a5b9c1c59bdce7c1f4a9b15e877d76 \ No newline at end of file diff --git a/docs/auto_examples/animate_spin.rst b/docs/auto_examples/animate_spin.rst index 43264bf3..a678d246 100644 --- a/docs/auto_examples/animate_spin.rst +++ b/docs/auto_examples/animate_spin.rst @@ -25,14 +25,14 @@ Create a rotating static plot In addition to plotting dynamic timeseries data, the spin feature can be used to visualize static data in an animated rotating plot. -.. GENERATED FROM PYTHON SOURCE LINES 10-25 +.. GENERATED FROM PYTHON SOURCE LINES 10-24 .. video:: /auto_examples/images/sphx_glr_animate_spin_001.mp4 :class: sphx-glr-single-img - :height: 480 - :width: 640 + :height: 960 + :width: 1280 :autoplay: @@ -51,17 +51,16 @@ visualize static data in an animated rotating plot. # import hypertools import hypertools as hyp - # load the geo - geo = hyp.load('weights_sample') + # load the data + data = hyp.load('weights_sample') # plot - ani_geo = geo.plot(fmt='.', animate='spin') - ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation + fig, ani = hyp.plot(data, fmt='.', animate='spin') .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 7.368 seconds) + **Total running time of the script:** (0 minutes 8.160 seconds) .. _sphx_glr_download_auto_examples_animate_spin.py: diff --git a/docs/auto_examples/animate_spin.zip b/docs/auto_examples/animate_spin.zip index bcb8a946..d7302f57 100644 Binary files a/docs/auto_examples/animate_spin.zip and b/docs/auto_examples/animate_spin.zip differ diff --git a/docs/auto_examples/animate_surface_morph.codeobj.json b/docs/auto_examples/animate_surface_morph.codeobj.json new file mode 100644 index 00000000..228999c9 --- /dev/null +++ b/docs/auto_examples/animate_surface_morph.codeobj.json @@ -0,0 +1,327 @@ +{ + "ani": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.animation", + "module_short": "matplotlib.animation", + "name": "FuncAnimation" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "FuncAnimation" + } + ], + "clouds": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "fig": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure" + } + ], + "fig.axes": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "FigureBase.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "FigureBase.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.artist", + "module_short": "matplotlib.artist", + "name": "Artist.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Artist.axes" + } + ], + "hyp.load": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "load" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "hypertools.plot.meshutil.smooth_hull_3d": [ + { + "is_class": false, + "is_explicit": true, + "module": "hypertools.plot.meshutil", + "module_short": "hypertools.plot.meshutil", + "name": "smooth_hull_3d" + } + ], + "load_shape": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + } + ], + "n_points": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "normalize_shape": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + } + ], + "np.abs": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ufunc" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "abs" + } + ], + "np.asarray": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "asarray" + } + ], + "np.float64": [ + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "float64" + }, + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "floating" + }, + { + "is_class": true, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + }, + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "inexact" + }, + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "number" + }, + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "generic" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "float64" + } + ], + "np.random.default_rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_2_1", + "module_short": "_cython_3_2_1", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "default_rng" + } + ], + "rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator" + } + ], + "rng.choice": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator.choice" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator.choice" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator.choice" + } + ], + "rotations": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "shapes": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "surface_spec": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/animate_surface_morph.ipynb b/docs/auto_examples/animate_surface_morph.ipynb new file mode 100644 index 00000000..71fb1c40 --- /dev/null +++ b/docs/auto_examples/animate_surface_morph.ipynb @@ -0,0 +1,54 @@ +{ + "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# Morphing hull surfaces through shapes\n\nBuilding on the *Morphing through the shapes zoo* example, HyperTools can\nalso render a smooth, lit convex-hull SURFACE around a moving point cloud\n(the ``surface=`` `hyp.plot` kwarg -- see :mod:`hypertools.plot.meshutil`\nand :mod:`hypertools.plot.surface`, GH #109) instead of just the raw\npoints. Combining `surface=` with `animate='morph'` (PR #272, maintainer\nrequest 2026-07-06) recomputes the moving cloud's smoothed hull mesh from\nscratch on every frame, shaded with a two-light Blinn-Phong model and\nbackface-culled for the current camera angle -- so the \"blob\" skin flows\ncontinuously as the underlying points rearrange themselves, all from one\n`hyp.plot` call. Camera rotation speed (degrees/frame) is always constant\nacross the whole animation, so a per-segment `rotations` list (below)\ncontrols how much SCREEN TIME each hold/transition gets, never how fast\nit spins. Since a convex hull cannot reproduce concave features,\nholds on concave shapes like the bunny necessarily render as a smooth,\nrounded blob; that loss of concavity is an expected trade-off of the\nhull-surface approach, not a bug. Hulls hug the data tightly BY\nCONSTRUCTION (each smoothing round pulls stray vertices back onto the\noriginal hull surface, see :func:`hypertools.plot.meshutil.smooth_hull_3d`)\nrather than via any fixed overshoot allowance, so the axes box never needs\na hand-computed fudge factor to contain the surface. A final, bounded,\ngrow-only rescale then guarantees at least 99% containment of the actual\npoints; for ordinary, reasonably-sampled clouds this rescale rarely does\nmore than nudge the mesh a few percent, and only grows large for very\nsparse clouds (rule of thumb: fewer than ~10 points), where a coarse,\nfew-vertex hull loses proportionally more to smoothing and needs more\ncorrection to recover that same 99% guarantee.\n\nTo keep the gallery build modest, only 5 of the 7 zoo shapes are used\n(dropping the very high point-count dragon and biplane meshes), and each\nshape is downsampled to 400 points before it's ever handed to `hyp.plot`\n(a hull's shape is set by its extreme points, so fewer interior points\nbarely change the rendered surface). This matters for more than just the\nper-frame ``ConvexHull`` cost: `hyp.plot` also builds one full hull per\nmorphing dataset up front (from whatever point cloud it's given) to size\nthe axes box safely for every frame, and a raw shapes-zoo cloud is dense\nenough that its hull can itself have tens of thousands of faces --\ndownsampling first keeps both that one-time sizing pass and every\nper-frame rebuild fast. The mesh smoothing is also capped at 2 rounds\nrather than the library default of 3 (roughly 20ms/frame instead of\n~100ms+, measured on this machine).\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nimport numpy as np\n\nimport hypertools as hyp\n\n# a subset of the shapes zoo -- smaller point-cloud shapes are used so the\n# per-frame convex-hull/smoothing pass stays fast (see module docstring)\nshapes = ['bunny', 'cube', 'sphere', 'teapot', 'vase']\n\n# a hull's shape is set by its extreme points, not its interior density, so\n# downsampling every shape to 400 points barely changes the rendered\n# surface while keeping both the one-time axes-sizing hull and every\n# per-frame rebuilt hull cheap (see module docstring)\nn_points = 400\nrng = np.random.default_rng(42)\n\n\ndef normalize_shape(points):\n \"\"\"Center and scale a point cloud into the hypertools [-1, 1] cube.\"\"\"\n points = np.asarray(points, dtype=np.float64)\n points = points - points.mean(axis=0)\n return points / np.abs(points).max()\n\n\ndef load_shape(name):\n \"\"\"Load and normalize one shapes-zoo cloud, downsampled to `n_points`\n (without replacement) so its hull stays cheap to compute.\"\"\"\n points = normalize_shape(hyp.load(name))\n idx = rng.choice(len(points), size=min(n_points, len(points)),\n replace=False)\n return points[idx]\n\n\nclouds = [load_shape(shape) for shape in shapes]\n\n# frame schedule: hold, morph, hold, morph, ..., hold -- 2 * n_shapes - 1 =\n# 9 segments in all. Holds get a slow, easy-to-watch full rotation (1)\n# while transitions get a brisk quarter-turn (0.25), so the camera visibly\n# steps forward every time one shape morphs into the next. Camera speed\n# stays CONSTANT (degrees/frame) across the whole animation, so each\n# segment's SCREEN TIME is proportional to its own rotation count instead\n# of split evenly: the 5 full-rotation holds get 60 frames each and the 4\n# quarter-turn transitions get 15 frames each (360 frames total @ 30 fps,\n# 12 sec, same total length as an equal-time split would have given).\nrotations = [1, 0.25] * (len(shapes) - 1) + [1]\n\n# surface look: a solid, lit blue-teal hull with 2 rounds of smoothing\n# (rather than the library default of 3) to keep per-frame cost low; the\n# points are kept only as a faint texture underneath the surface (set\n# below), which does the visual work\nsurface_spec = {\n 'alpha': 0.97,\n 'color': '#2E86AB',\n 'smoothing': 2,\n 'keep_points': True,\n}\n\n# morph_samples=n_points: every shape is ALREADY downsampled to exactly\n# n_points above, so under the new full-sample-with-duplication semantics\n# (PR #272 follow-up, 2026-07-06) this is a no-op safety cap -- no shape\n# ever exceeds n_points, so none is downsampled again and no duplication\n# is needed (all 5 clouds already share the same point count).\nfig, ani = hyp.plot(clouds, fmt='.', color='k', markersize=0.6,\n animate='morph', rotations=rotations,\n duration=12, frame_rate=30,\n morph_samples=n_points, surface=surface_spec)\n\n# fade the point layer to a subtle texture underneath the hull surface\nfig.axes[0].get_lines()[0].set_alpha(0.25)" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/animate_surface_morph.py b/docs/auto_examples/animate_surface_morph.py new file mode 100644 index 00000000..ef0df439 --- /dev/null +++ b/docs/auto_examples/animate_surface_morph.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +""" +===================================== +Morphing hull surfaces through shapes +===================================== + +Building on the *Morphing through the shapes zoo* example, HyperTools can +also render a smooth, lit convex-hull SURFACE around a moving point cloud +(the ``surface=`` `hyp.plot` kwarg -- see :mod:`hypertools.plot.meshutil` +and :mod:`hypertools.plot.surface`, GH #109) instead of just the raw +points. Combining `surface=` with `animate='morph'` (PR #272, maintainer +request 2026-07-06) recomputes the moving cloud's smoothed hull mesh from +scratch on every frame, shaded with a two-light Blinn-Phong model and +backface-culled for the current camera angle -- so the "blob" skin flows +continuously as the underlying points rearrange themselves, all from one +`hyp.plot` call. Camera rotation speed (degrees/frame) is always constant +across the whole animation, so a per-segment `rotations` list (below) +controls how much SCREEN TIME each hold/transition gets, never how fast +it spins. Since a convex hull cannot reproduce concave features, +holds on concave shapes like the bunny necessarily render as a smooth, +rounded blob; that loss of concavity is an expected trade-off of the +hull-surface approach, not a bug. Hulls hug the data tightly BY +CONSTRUCTION (each smoothing round pulls stray vertices back onto the +original hull surface, see :func:`hypertools.plot.meshutil.smooth_hull_3d`) +rather than via any fixed overshoot allowance, so the axes box never needs +a hand-computed fudge factor to contain the surface. A final, bounded, +grow-only rescale then guarantees at least 99% containment of the actual +points; for ordinary, reasonably-sampled clouds this rescale rarely does +more than nudge the mesh a few percent, and only grows large for very +sparse clouds (rule of thumb: fewer than ~10 points), where a coarse, +few-vertex hull loses proportionally more to smoothing and needs more +correction to recover that same 99% guarantee. + +To keep the gallery build modest, only 5 of the 7 zoo shapes are used +(dropping the very high point-count dragon and biplane meshes), and each +shape is downsampled to 400 points before it's ever handed to `hyp.plot` +(a hull's shape is set by its extreme points, so fewer interior points +barely change the rendered surface). This matters for more than just the +per-frame ``ConvexHull`` cost: `hyp.plot` also builds one full hull per +morphing dataset up front (from whatever point cloud it's given) to size +the axes box safely for every frame, and a raw shapes-zoo cloud is dense +enough that its hull can itself have tens of thousands of faces -- +downsampling first keeps both that one-time sizing pass and every +per-frame rebuild fast. The mesh smoothing is also capped at 2 rounds +rather than the library default of 3 (roughly 20ms/frame instead of +~100ms+, measured on this machine). +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +import numpy as np + +import hypertools as hyp + +# a subset of the shapes zoo -- smaller point-cloud shapes are used so the +# per-frame convex-hull/smoothing pass stays fast (see module docstring) +shapes = ['bunny', 'cube', 'sphere', 'teapot', 'vase'] + +# a hull's shape is set by its extreme points, not its interior density, so +# downsampling every shape to 400 points barely changes the rendered +# surface while keeping both the one-time axes-sizing hull and every +# per-frame rebuilt hull cheap (see module docstring) +n_points = 400 +rng = np.random.default_rng(42) + + +def normalize_shape(points): + """Center and scale a point cloud into the hypertools [-1, 1] cube.""" + points = np.asarray(points, dtype=np.float64) + points = points - points.mean(axis=0) + return points / np.abs(points).max() + + +def load_shape(name): + """Load and normalize one shapes-zoo cloud, downsampled to `n_points` + (without replacement) so its hull stays cheap to compute.""" + points = normalize_shape(hyp.load(name)) + idx = rng.choice(len(points), size=min(n_points, len(points)), + replace=False) + return points[idx] + + +clouds = [load_shape(shape) for shape in shapes] + +# frame schedule: hold, morph, hold, morph, ..., hold -- 2 * n_shapes - 1 = +# 9 segments in all. Holds get a slow, easy-to-watch full rotation (1) +# while transitions get a brisk quarter-turn (0.25), so the camera visibly +# steps forward every time one shape morphs into the next. Camera speed +# stays CONSTANT (degrees/frame) across the whole animation, so each +# segment's SCREEN TIME is proportional to its own rotation count instead +# of split evenly: the 5 full-rotation holds get 60 frames each and the 4 +# quarter-turn transitions get 15 frames each (360 frames total @ 30 fps, +# 12 sec, same total length as an equal-time split would have given). +rotations = [1, 0.25] * (len(shapes) - 1) + [1] + +# surface look: a solid, lit blue-teal hull with 2 rounds of smoothing +# (rather than the library default of 3) to keep per-frame cost low; the +# points are kept only as a faint texture underneath the surface (set +# below), which does the visual work +surface_spec = { + 'alpha': 0.97, + 'color': '#2E86AB', + 'smoothing': 2, + 'keep_points': True, +} + +# morph_samples=n_points: every shape is ALREADY downsampled to exactly +# n_points above, so under the new full-sample-with-duplication semantics +# (PR #272 follow-up, 2026-07-06) this is a no-op safety cap -- no shape +# ever exceeds n_points, so none is downsampled again and no duplication +# is needed (all 5 clouds already share the same point count). +fig, ani = hyp.plot(clouds, fmt='.', color='k', markersize=0.6, + animate='morph', rotations=rotations, + duration=12, frame_rate=30, + morph_samples=n_points, surface=surface_spec) + +# fade the point layer to a subtle texture underneath the hull surface +fig.axes[0].get_lines()[0].set_alpha(0.25) diff --git a/docs/auto_examples/animate_surface_morph.py.md5 b/docs/auto_examples/animate_surface_morph.py.md5 new file mode 100644 index 00000000..12cd54de --- /dev/null +++ b/docs/auto_examples/animate_surface_morph.py.md5 @@ -0,0 +1 @@ +32455431c69646c09a2549683f1b6277 \ No newline at end of file diff --git a/docs/auto_examples/animate_surface_morph.rst b/docs/auto_examples/animate_surface_morph.rst new file mode 100644 index 00000000..448aacf9 --- /dev/null +++ b/docs/auto_examples/animate_surface_morph.rst @@ -0,0 +1,185 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/animate_surface_morph.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_animate_surface_morph.py: + + +===================================== +Morphing hull surfaces through shapes +===================================== + +Building on the *Morphing through the shapes zoo* example, HyperTools can +also render a smooth, lit convex-hull SURFACE around a moving point cloud +(the ``surface=`` `hyp.plot` kwarg -- see :mod:`hypertools.plot.meshutil` +and :mod:`hypertools.plot.surface`, GH #109) instead of just the raw +points. Combining `surface=` with `animate='morph'` (PR #272, maintainer +request 2026-07-06) recomputes the moving cloud's smoothed hull mesh from +scratch on every frame, shaded with a two-light Blinn-Phong model and +backface-culled for the current camera angle -- so the "blob" skin flows +continuously as the underlying points rearrange themselves, all from one +`hyp.plot` call. Camera rotation speed (degrees/frame) is always constant +across the whole animation, so a per-segment `rotations` list (below) +controls how much SCREEN TIME each hold/transition gets, never how fast +it spins. Since a convex hull cannot reproduce concave features, +holds on concave shapes like the bunny necessarily render as a smooth, +rounded blob; that loss of concavity is an expected trade-off of the +hull-surface approach, not a bug. Hulls hug the data tightly BY +CONSTRUCTION (each smoothing round pulls stray vertices back onto the +original hull surface, see :func:`hypertools.plot.meshutil.smooth_hull_3d`) +rather than via any fixed overshoot allowance, so the axes box never needs +a hand-computed fudge factor to contain the surface. A final, bounded, +grow-only rescale then guarantees at least 99% containment of the actual +points; for ordinary, reasonably-sampled clouds this rescale rarely does +more than nudge the mesh a few percent, and only grows large for very +sparse clouds (rule of thumb: fewer than ~10 points), where a coarse, +few-vertex hull loses proportionally more to smoothing and needs more +correction to recover that same 99% guarantee. + +To keep the gallery build modest, only 5 of the 7 zoo shapes are used +(dropping the very high point-count dragon and biplane meshes), and each +shape is downsampled to 400 points before it's ever handed to `hyp.plot` +(a hull's shape is set by its extreme points, so fewer interior points +barely change the rendered surface). This matters for more than just the +per-frame ``ConvexHull`` cost: `hyp.plot` also builds one full hull per +morphing dataset up front (from whatever point cloud it's given) to size +the axes box safely for every frame, and a raw shapes-zoo cloud is dense +enough that its hull can itself have tens of thousands of faces -- +downsampling first keeps both that one-time sizing pass and every +per-frame rebuild fast. The mesh smoothing is also capped at 2 rounds +rather than the library default of 3 (roughly 20ms/frame instead of +~100ms+, measured on this machine). + +.. GENERATED FROM PYTHON SOURCE LINES 48-120 + + + +.. video:: /auto_examples/images/sphx_glr_animate_surface_morph_001.mp4 + :class: sphx-glr-single-img + :height: 480 + :width: 640 + :autoplay: + + + + + + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + import numpy as np + + import hypertools as hyp + + # a subset of the shapes zoo -- smaller point-cloud shapes are used so the + # per-frame convex-hull/smoothing pass stays fast (see module docstring) + shapes = ['bunny', 'cube', 'sphere', 'teapot', 'vase'] + + # a hull's shape is set by its extreme points, not its interior density, so + # downsampling every shape to 400 points barely changes the rendered + # surface while keeping both the one-time axes-sizing hull and every + # per-frame rebuilt hull cheap (see module docstring) + n_points = 400 + rng = np.random.default_rng(42) + + + def normalize_shape(points): + """Center and scale a point cloud into the hypertools [-1, 1] cube.""" + points = np.asarray(points, dtype=np.float64) + points = points - points.mean(axis=0) + return points / np.abs(points).max() + + + def load_shape(name): + """Load and normalize one shapes-zoo cloud, downsampled to `n_points` + (without replacement) so its hull stays cheap to compute.""" + points = normalize_shape(hyp.load(name)) + idx = rng.choice(len(points), size=min(n_points, len(points)), + replace=False) + return points[idx] + + + clouds = [load_shape(shape) for shape in shapes] + + # frame schedule: hold, morph, hold, morph, ..., hold -- 2 * n_shapes - 1 = + # 9 segments in all. Holds get a slow, easy-to-watch full rotation (1) + # while transitions get a brisk quarter-turn (0.25), so the camera visibly + # steps forward every time one shape morphs into the next. Camera speed + # stays CONSTANT (degrees/frame) across the whole animation, so each + # segment's SCREEN TIME is proportional to its own rotation count instead + # of split evenly: the 5 full-rotation holds get 60 frames each and the 4 + # quarter-turn transitions get 15 frames each (360 frames total @ 30 fps, + # 12 sec, same total length as an equal-time split would have given). + rotations = [1, 0.25] * (len(shapes) - 1) + [1] + + # surface look: a solid, lit blue-teal hull with 2 rounds of smoothing + # (rather than the library default of 3) to keep per-frame cost low; the + # points are kept only as a faint texture underneath the surface (set + # below), which does the visual work + surface_spec = { + 'alpha': 0.97, + 'color': '#2E86AB', + 'smoothing': 2, + 'keep_points': True, + } + + # morph_samples=n_points: every shape is ALREADY downsampled to exactly + # n_points above, so under the new full-sample-with-duplication semantics + # (PR #272 follow-up, 2026-07-06) this is a no-op safety cap -- no shape + # ever exceeds n_points, so none is downsampled again and no duplication + # is needed (all 5 clouds already share the same point count). + fig, ani = hyp.plot(clouds, fmt='.', color='k', markersize=0.6, + animate='morph', rotations=rotations, + duration=12, frame_rate=30, + morph_samples=n_points, surface=surface_spec) + + # fade the point layer to a subtle texture underneath the hull surface + fig.axes[0].get_lines()[0].set_alpha(0.25) + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (1 minutes 57.221 seconds) + + +.. _sphx_glr_download_auto_examples_animate_surface_morph.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: animate_surface_morph.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: animate_surface_morph.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: animate_surface_morph.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/animate_surface_morph.zip b/docs/auto_examples/animate_surface_morph.zip new file mode 100644 index 00000000..59df2fad Binary files /dev/null and b/docs/auto_examples/animate_surface_morph.zip differ diff --git a/docs/auto_examples/animate_trails_mix.codeobj.json b/docs/auto_examples/animate_trails_mix.codeobj.json new file mode 100644 index 00000000..0bb5da5e --- /dev/null +++ b/docs/auto_examples/animate_trails_mix.codeobj.json @@ -0,0 +1,214 @@ +{ + "ani": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.animation", + "module_short": "matplotlib.animation", + "name": "FuncAnimation" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "FuncAnimation" + } + ], + "data_a": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "data_b": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "data_c": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "fig": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "n_time": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "np.column_stack": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "column_stack" + } + ], + "np.cos": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ufunc" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "cos" + } + ], + "np.linspace": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "linspace" + } + ], + "np.pi": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "pi" + } + ], + "np.random.default_rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_2_1", + "module_short": "_cython_3_2_1", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "default_rng" + } + ], + "np.sin": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ufunc" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "sin" + } + ], + "rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator" + } + ], + "t": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/animate_trails_mix.ipynb b/docs/auto_examples/animate_trails_mix.ipynb new file mode 100644 index 00000000..473eeace --- /dev/null +++ b/docs/auto_examples/animate_trails_mix.ipynb @@ -0,0 +1,54 @@ +{ + "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# Mixing trail styles per dataset\n\n`chemtrails`, `precog`, and `bullettime` each accept a per-dataset list of\nbools instead of a single bool, so different datasets in the same animation\ncan show different trail styles (GH #127): a low-opacity trace of the past\n(chemtrails), of the future (precog), or of the entire timeseries at once\n(bullettime -- equivalent to chemtrails AND precog together).\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nimport numpy as np\n\nimport hypertools as hyp\n\nrng = np.random.default_rng(4)\nn_time = 40\nt = np.linspace(0, 4 * np.pi, n_time)\n\ndata_a = np.column_stack([np.cos(t), np.sin(t), t / 4])\ndata_b = np.column_stack([np.cos(t), -np.sin(t), t / 4]) + [3, 0, 0]\ndata_c = np.column_stack([np.sin(t), np.cos(t), t / 4]) + [-3, 0, 0]\n\n# dataset 0: chemtrails (past trail) only\n# dataset 1: precog (future trail) only\n# dataset 2: bullettime (full trail, past + future) only\nfig, ani = hyp.plot(\n [data_a, data_b, data_c],\n animate=True,\n chemtrails=[True, False, False],\n precog=[False, True, False],\n bullettime=[False, False, True],\n)" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/animate_trails_mix.py b/docs/auto_examples/animate_trails_mix.py new file mode 100644 index 00000000..00723413 --- /dev/null +++ b/docs/auto_examples/animate_trails_mix.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +""" +============================= +Mixing trail styles per dataset +============================= + +`chemtrails`, `precog`, and `bullettime` each accept a per-dataset list of +bools instead of a single bool, so different datasets in the same animation +can show different trail styles (GH #127): a low-opacity trace of the past +(chemtrails), of the future (precog), or of the entire timeseries at once +(bullettime -- equivalent to chemtrails AND precog together). +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +import numpy as np + +import hypertools as hyp + +rng = np.random.default_rng(4) +n_time = 40 +t = np.linspace(0, 4 * np.pi, n_time) + +data_a = np.column_stack([np.cos(t), np.sin(t), t / 4]) +data_b = np.column_stack([np.cos(t), -np.sin(t), t / 4]) + [3, 0, 0] +data_c = np.column_stack([np.sin(t), np.cos(t), t / 4]) + [-3, 0, 0] + +# dataset 0: chemtrails (past trail) only +# dataset 1: precog (future trail) only +# dataset 2: bullettime (full trail, past + future) only +fig, ani = hyp.plot( + [data_a, data_b, data_c], + animate=True, + chemtrails=[True, False, False], + precog=[False, True, False], + bullettime=[False, False, True], +) diff --git a/docs/auto_examples/animate_trails_mix.py.md5 b/docs/auto_examples/animate_trails_mix.py.md5 new file mode 100644 index 00000000..603015cc --- /dev/null +++ b/docs/auto_examples/animate_trails_mix.py.md5 @@ -0,0 +1 @@ +faa3c47aa4604a05bf314e0e9932cdfb \ No newline at end of file diff --git a/docs/auto_examples/animate_trails_mix.rst b/docs/auto_examples/animate_trails_mix.rst new file mode 100644 index 00000000..abc53adc --- /dev/null +++ b/docs/auto_examples/animate_trails_mix.rst @@ -0,0 +1,104 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/animate_trails_mix.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_animate_trails_mix.py: + + +============================= +Mixing trail styles per dataset +============================= + +`chemtrails`, `precog`, and `bullettime` each accept a per-dataset list of +bools instead of a single bool, so different datasets in the same animation +can show different trail styles (GH #127): a low-opacity trace of the past +(chemtrails), of the future (precog), or of the entire timeseries at once +(bullettime -- equivalent to chemtrails AND precog together). + +.. GENERATED FROM PYTHON SOURCE LINES 13-39 + + + +.. video:: /auto_examples/images/sphx_glr_animate_trails_mix_001.mp4 + :class: sphx-glr-single-img + :height: 480 + :width: 640 + :autoplay: + + + + + + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + import numpy as np + + import hypertools as hyp + + rng = np.random.default_rng(4) + n_time = 40 + t = np.linspace(0, 4 * np.pi, n_time) + + data_a = np.column_stack([np.cos(t), np.sin(t), t / 4]) + data_b = np.column_stack([np.cos(t), -np.sin(t), t / 4]) + [3, 0, 0] + data_c = np.column_stack([np.sin(t), np.cos(t), t / 4]) + [-3, 0, 0] + + # dataset 0: chemtrails (past trail) only + # dataset 1: precog (future trail) only + # dataset 2: bullettime (full trail, past + future) only + fig, ani = hyp.plot( + [data_a, data_b, data_c], + animate=True, + chemtrails=[True, False, False], + precog=[False, True, False], + bullettime=[False, False, True], + ) + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 6.351 seconds) + + +.. _sphx_glr_download_auto_examples_animate_trails_mix.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: animate_trails_mix.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: animate_trails_mix.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: animate_trails_mix.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/animate_trails_mix.zip b/docs/auto_examples/animate_trails_mix.zip new file mode 100644 index 00000000..51a80c45 Binary files /dev/null and b/docs/auto_examples/animate_trails_mix.zip differ diff --git a/docs/auto_examples/auto_examples_jupyter.zip b/docs/auto_examples/auto_examples_jupyter.zip index 7dec4750..435a7a5a 100644 Binary files a/docs/auto_examples/auto_examples_jupyter.zip and b/docs/auto_examples/auto_examples_jupyter.zip differ diff --git a/docs/auto_examples/auto_examples_python.zip b/docs/auto_examples/auto_examples_python.zip index 7f952d5a..10167e70 100644 Binary files a/docs/auto_examples/auto_examples_python.zip and b/docs/auto_examples/auto_examples_python.zip differ diff --git a/docs/auto_examples/chemtrails.codeobj.json b/docs/auto_examples/chemtrails.codeobj.json index 1503c46f..dc560397 100644 --- a/docs/auto_examples/chemtrails.codeobj.json +++ b/docs/auto_examples/chemtrails.codeobj.json @@ -15,71 +15,48 @@ "name": "FuncAnimation" } ], - "ani_geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "ani_geo.line_ani": [ + "fig": [ { "is_class": false, "is_explicit": false, - "module": "matplotlib.animation", - "module_short": "matplotlib.animation", - "name": "FuncAnimation" + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" }, { "is_class": false, "is_explicit": false, "module": "matplotlib", "module_short": "matplotlib", - "name": "FuncAnimation" + "name": "Figure" } ], - "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.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -92,7 +69,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/chemtrails.ipynb b/docs/auto_examples/chemtrails.ipynb index 6f5a30ac..a28c56ca 100644 --- a/docs/auto_examples/chemtrails.ipynb +++ b/docs/auto_examples/chemtrails.ipynb @@ -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# Chemtrails\n\nThe past trajectory of an animated plot can be visualized with the chemtrails\nargument. This displays a low opacity version of the trace behind the\ncurrent points being plotted. This can be used in conjunction with the\nprecog argument to plot a low-opacity trace of the entire timeseries.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_chemtrails_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ndata = hyp.load('weights_avg')\n\n# plot\nfig, ani = hyp.plot(data, animate=True, chemtrails=True)" + ] + } + ], + "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# Chemtrails\n\nThe past trajectory of an animated plot can be visualized with the chemtrails\nargument. This displays a low opacity version of the trace behind the\ncurrent points being plotted. This can be used in conjunction with the\nprecog argument to plot a low-opacity trace of the entire timeseries.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_chemtrails_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ngeo = hyp.load('weights_avg')\n\n# plot\nani_geo = geo.plot(animate=True, chemtrails=True)\nani = ani_geo.line_ani # the underlying matplotlib FuncAnimation" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/chemtrails.py b/docs/auto_examples/chemtrails.py index 6d7b3814..d421c08b 100644 --- a/docs/auto_examples/chemtrails.py +++ b/docs/auto_examples/chemtrails.py @@ -19,8 +19,7 @@ import hypertools as hyp # load example data -geo = hyp.load('weights_avg') +data = hyp.load('weights_avg') # plot -ani_geo = geo.plot(animate=True, chemtrails=True) -ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation +fig, ani = hyp.plot(data, animate=True, chemtrails=True) diff --git a/docs/auto_examples/chemtrails.py.md5 b/docs/auto_examples/chemtrails.py.md5 index 13fddaba..b42d8daa 100644 --- a/docs/auto_examples/chemtrails.py.md5 +++ b/docs/auto_examples/chemtrails.py.md5 @@ -1 +1 @@ -9661f229ffed663458068c130b272445 \ No newline at end of file +0642dc809cbac34d0382029d6964571d \ No newline at end of file diff --git a/docs/auto_examples/chemtrails.rst b/docs/auto_examples/chemtrails.rst index 7782ea00..bb2fdcb2 100644 --- a/docs/auto_examples/chemtrails.rst +++ b/docs/auto_examples/chemtrails.rst @@ -27,7 +27,7 @@ argument. This displays a low opacity version of the trace behind the current points being plotted. This can be used in conjunction with the precog argument to plot a low-opacity trace of the entire timeseries. -.. GENERATED FROM PYTHON SOURCE LINES 12-27 +.. GENERATED FROM PYTHON SOURCE LINES 12-26 @@ -54,16 +54,15 @@ precog argument to plot a low-opacity trace of the entire timeseries. import hypertools as hyp # load example data - geo = hyp.load('weights_avg') + data = hyp.load('weights_avg') # plot - ani_geo = geo.plot(animate=True, chemtrails=True) - ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation + fig, ani = hyp.plot(data, animate=True, chemtrails=True) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 7.915 seconds) + **Total running time of the script:** (0 minutes 6.295 seconds) .. _sphx_glr_download_auto_examples_chemtrails.py: diff --git a/docs/auto_examples/chemtrails.zip b/docs/auto_examples/chemtrails.zip index 397fc738..fe1bd48f 100644 Binary files a/docs/auto_examples/chemtrails.zip and b/docs/auto_examples/chemtrails.zip differ diff --git a/docs/auto_examples/explore.codeobj.json b/docs/auto_examples/explore.codeobj.json index 11d4a30b..fae7d364 100644 --- a/docs/auto_examples/explore.codeobj.json +++ b/docs/auto_examples/explore.codeobj.json @@ -1,37 +1,30 @@ { - "geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -44,7 +37,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/explore.ipynb b/docs/auto_examples/explore.ipynb index ba6773dc..18a1817d 100644 --- a/docs/auto_examples/explore.ipynb +++ b/docs/auto_examples/explore.ipynb @@ -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# Explore mode!\n\nExplore mode is an experimental feature that allows you to (not surprisingly)\nexplore the points in your dataset. When you hover over the points, a label\nwill pop up that will help you identify the datapoint. You can customize the\nlabels by passing a list of labels to the `label(s)` kwarg. Alternatively, if\nyou don't pass a list of labels, the labels will be the index of the datapoint,\nalong with the PCA coordinate.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_explore_thumb.png'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ndata = hyp.load('weights_sample')\n\n# plot\nhyp.plot(data, fmt='.', explore=True)" + ] + } + ], + "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# Explore mode!\n\nExplore mode is an experimental feature that allows you to (not surprisingly)\nexplore the points in your dataset. When you hover over the points, a label\nwill pop up that will help you identify the datapoint. You can customize the\nlabels by passing a list of labels to the `label(s)` kwarg. Alternatively, if\nyou don't pass a list of labels, the labels will be the index of the datapoint,\nalong with the PCA coordinate.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_explore_thumb.png'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ngeo = hyp.load('weights_sample')\n\n# plot\ngeo.plot(fmt='.', explore=True)" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/explore.py b/docs/auto_examples/explore.py index 7f397710..ee29adc5 100644 --- a/docs/auto_examples/explore.py +++ b/docs/auto_examples/explore.py @@ -21,7 +21,7 @@ import hypertools as hyp # load example data -geo = hyp.load('weights_sample') +data = hyp.load('weights_sample') # plot -geo.plot(fmt='.', explore=True) +hyp.plot(data, fmt='.', explore=True) diff --git a/docs/auto_examples/explore.py.md5 b/docs/auto_examples/explore.py.md5 index 9de6b0c8..79a041bb 100644 --- a/docs/auto_examples/explore.py.md5 +++ b/docs/auto_examples/explore.py.md5 @@ -1 +1 @@ -45f4a8e6497d26fda8de224c7f4355d8 \ No newline at end of file +96a34cde5b92640cfac770572d78635f \ No newline at end of file diff --git a/docs/auto_examples/explore.rst b/docs/auto_examples/explore.rst index 3a48e468..4fa0db13 100644 --- a/docs/auto_examples/explore.rst +++ b/docs/auto_examples/explore.rst @@ -54,15 +54,15 @@ along with the PCA coordinate. import hypertools as hyp # load example data - geo = hyp.load('weights_sample') + data = hyp.load('weights_sample') # plot - geo.plot(fmt='.', explore=True) + hyp.plot(data, fmt='.', explore=True) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.104 seconds) + **Total running time of the script:** (0 minutes 0.024 seconds) .. _sphx_glr_download_auto_examples_explore.py: diff --git a/docs/auto_examples/explore.zip b/docs/auto_examples/explore.zip index 10acc517..e7c5a7b5 100644 Binary files a/docs/auto_examples/explore.zip and b/docs/auto_examples/explore.zip differ diff --git a/docs/auto_examples/images/sphx_glr_analyze_001.png b/docs/auto_examples/images/sphx_glr_analyze_001.png index edd4e523..10721859 100644 Binary files a/docs/auto_examples/images/sphx_glr_analyze_001.png and b/docs/auto_examples/images/sphx_glr_analyze_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_animate_001.gif b/docs/auto_examples/images/sphx_glr_animate_001.gif index ae2ac712..f8e6a56c 100644 Binary files a/docs/auto_examples/images/sphx_glr_animate_001.gif and b/docs/auto_examples/images/sphx_glr_animate_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_animate_001.mp4 b/docs/auto_examples/images/sphx_glr_animate_001.mp4 index e7709f5c..43057341 100644 Binary files a/docs/auto_examples/images/sphx_glr_animate_001.mp4 and b/docs/auto_examples/images/sphx_glr_animate_001.mp4 differ diff --git a/docs/auto_examples/images/sphx_glr_animate_MDS_001.gif b/docs/auto_examples/images/sphx_glr_animate_MDS_001.gif index 3516503a..0778128e 100644 Binary files a/docs/auto_examples/images/sphx_glr_animate_MDS_001.gif and b/docs/auto_examples/images/sphx_glr_animate_MDS_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_animate_MDS_001.mp4 b/docs/auto_examples/images/sphx_glr_animate_MDS_001.mp4 index 2db0fd71..e4fb2ebc 100644 Binary files a/docs/auto_examples/images/sphx_glr_animate_MDS_001.mp4 and b/docs/auto_examples/images/sphx_glr_animate_MDS_001.mp4 differ diff --git a/docs/auto_examples/images/sphx_glr_animate_plotly_001.html b/docs/auto_examples/images/sphx_glr_animate_plotly_001.html index 33801b9a..a5c4d286 100644 --- a/docs/auto_examples/images/sphx_glr_animate_plotly_001.html +++ b/docs/auto_examples/images/sphx_glr_animate_plotly_001.html @@ -2,8 +2,8 @@
-
\ No newline at end of file diff --git a/docs/auto_examples/images/sphx_glr_animate_plotly_001.png b/docs/auto_examples/images/sphx_glr_animate_plotly_001.png index e7a47289..ca913afc 100644 Binary files a/docs/auto_examples/images/sphx_glr_animate_plotly_001.png and b/docs/auto_examples/images/sphx_glr_animate_plotly_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_animate_spin_001.gif b/docs/auto_examples/images/sphx_glr_animate_spin_001.gif index 7c4e5377..ac130927 100644 Binary files a/docs/auto_examples/images/sphx_glr_animate_spin_001.gif and b/docs/auto_examples/images/sphx_glr_animate_spin_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_animate_spin_001.mp4 b/docs/auto_examples/images/sphx_glr_animate_spin_001.mp4 index 67eb375e..be7e2dbb 100644 Binary files a/docs/auto_examples/images/sphx_glr_animate_spin_001.mp4 and b/docs/auto_examples/images/sphx_glr_animate_spin_001.mp4 differ diff --git a/docs/auto_examples/images/sphx_glr_animate_surface_morph_001.gif b/docs/auto_examples/images/sphx_glr_animate_surface_morph_001.gif new file mode 100644 index 00000000..61a5f68d Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_animate_surface_morph_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_animate_surface_morph_001.mp4 b/docs/auto_examples/images/sphx_glr_animate_surface_morph_001.mp4 new file mode 100644 index 00000000..3efaa1c8 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_animate_surface_morph_001.mp4 differ diff --git a/docs/auto_examples/images/sphx_glr_animate_trails_mix_001.gif b/docs/auto_examples/images/sphx_glr_animate_trails_mix_001.gif new file mode 100644 index 00000000..f0aebc61 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_animate_trails_mix_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_animate_trails_mix_001.mp4 b/docs/auto_examples/images/sphx_glr_animate_trails_mix_001.mp4 new file mode 100644 index 00000000..42f4f566 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_animate_trails_mix_001.mp4 differ diff --git a/docs/auto_examples/images/sphx_glr_chemtrails_001.gif b/docs/auto_examples/images/sphx_glr_chemtrails_001.gif index 0212e8e0..e3fa127b 100644 Binary files a/docs/auto_examples/images/sphx_glr_chemtrails_001.gif and b/docs/auto_examples/images/sphx_glr_chemtrails_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_chemtrails_001.mp4 b/docs/auto_examples/images/sphx_glr_chemtrails_001.mp4 index a9bbaf84..9536cd9b 100644 Binary files a/docs/auto_examples/images/sphx_glr_chemtrails_001.mp4 and b/docs/auto_examples/images/sphx_glr_chemtrails_001.mp4 differ diff --git a/docs/auto_examples/images/sphx_glr_explore_001.png b/docs/auto_examples/images/sphx_glr_explore_001.png index 3fbd497d..ab9619d4 100644 Binary files a/docs/auto_examples/images/sphx_glr_explore_001.png and b/docs/auto_examples/images/sphx_glr_explore_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_2D_001.png b/docs/auto_examples/images/sphx_glr_plot_2D_001.png index 07afc263..d7080937 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_2D_001.png and b/docs/auto_examples/images/sphx_glr_plot_2D_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_PPCA_001.png b/docs/auto_examples/images/sphx_glr_plot_PPCA_001.png index 087a40f8..c990e4ac 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_PPCA_001.png and b/docs/auto_examples/images/sphx_glr_plot_PPCA_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_TSNE_001.png b/docs/auto_examples/images/sphx_glr_plot_TSNE_001.png index 1fa496e5..d9760ea4 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_TSNE_001.png and b/docs/auto_examples/images/sphx_glr_plot_TSNE_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_UMAP_001.png b/docs/auto_examples/images/sphx_glr_plot_UMAP_001.png index 1c1b25ae..06dd5bcd 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_UMAP_001.png and b/docs/auto_examples/images/sphx_glr_plot_UMAP_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_align_001.png b/docs/auto_examples/images/sphx_glr_plot_align_001.png index dc87966b..82b23e54 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_align_001.png and b/docs/auto_examples/images/sphx_glr_plot_align_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_basic_001.png b/docs/auto_examples/images/sphx_glr_plot_basic_001.png index 69dc027a..ab9619d4 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_basic_001.png and b/docs/auto_examples/images/sphx_glr_plot_basic_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_basic_002.html b/docs/auto_examples/images/sphx_glr_plot_basic_002.html new file mode 100644 index 00000000..f2848e79 --- /dev/null +++ b/docs/auto_examples/images/sphx_glr_plot_basic_002.html @@ -0,0 +1,9 @@ + + + +
+
+ + \ No newline at end of file diff --git a/docs/auto_examples/images/sphx_glr_plot_basic_002.png b/docs/auto_examples/images/sphx_glr_plot_basic_002.png new file mode 100644 index 00000000..e7a47289 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_basic_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_clusters2_001.png b/docs/auto_examples/images/sphx_glr_plot_clusters2_001.png index c45151a1..ca1a5a43 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_clusters2_001.png and b/docs/auto_examples/images/sphx_glr_plot_clusters2_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_clusters3_001.png b/docs/auto_examples/images/sphx_glr_plot_clusters3_001.png index 43029ad7..be787f1f 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_clusters3_001.png and b/docs/auto_examples/images/sphx_glr_plot_clusters3_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_clusters_001.png b/docs/auto_examples/images/sphx_glr_plot_clusters_001.png index dd9252c2..14599e36 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_clusters_001.png and b/docs/auto_examples/images/sphx_glr_plot_clusters_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_colorbar_001.png b/docs/auto_examples/images/sphx_glr_plot_colorbar_001.png new file mode 100644 index 00000000..2a10c9d3 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_colorbar_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_colorbar_002.png b/docs/auto_examples/images/sphx_glr_plot_colorbar_002.png new file mode 100644 index 00000000..b0d4f2da Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_colorbar_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_corpus_001.png b/docs/auto_examples/images/sphx_glr_plot_corpus_001.png index 4c5f3f0e..f4abd111 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_corpus_001.png and b/docs/auto_examples/images/sphx_glr_plot_corpus_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_dataframe_001.png b/docs/auto_examples/images/sphx_glr_plot_dataframe_001.png index 2eaa3f7d..094f8b29 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_dataframe_001.png and b/docs/auto_examples/images/sphx_glr_plot_dataframe_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_density_001.png b/docs/auto_examples/images/sphx_glr_plot_density_001.png new file mode 100644 index 00000000..7b2b66a5 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_density_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_density_002.png b/docs/auto_examples/images/sphx_glr_plot_density_002.png new file mode 100644 index 00000000..40cc01d8 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_density_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_density_003.png b/docs/auto_examples/images/sphx_glr_plot_density_003.png new file mode 100644 index 00000000..eb75872d Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_density_003.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_describe_001.png b/docs/auto_examples/images/sphx_glr_plot_describe_001.png index 76881a8d..676b2014 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_describe_001.png and b/docs/auto_examples/images/sphx_glr_plot_describe_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_digits_001.png b/docs/auto_examples/images/sphx_glr_plot_digits_001.png index 1a09d5c7..4cbb5a6a 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_digits_001.png and b/docs/auto_examples/images/sphx_glr_plot_digits_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_geo_001.png b/docs/auto_examples/images/sphx_glr_plot_geo_001.png index 2eaa3f7d..bb7ec061 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_geo_001.png and b/docs/auto_examples/images/sphx_glr_plot_geo_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_geo_002.png b/docs/auto_examples/images/sphx_glr_plot_geo_002.png index 1c0c099d..bb7ec061 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_geo_002.png and b/docs/auto_examples/images/sphx_glr_plot_geo_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_geo_003.html b/docs/auto_examples/images/sphx_glr_plot_geo_003.html new file mode 100644 index 00000000..8c9b4e07 --- /dev/null +++ b/docs/auto_examples/images/sphx_glr_plot_geo_003.html @@ -0,0 +1,9 @@ + + + +
+
+ + \ No newline at end of file diff --git a/docs/auto_examples/images/sphx_glr_plot_geo_003.png b/docs/auto_examples/images/sphx_glr_plot_geo_003.png new file mode 100644 index 00000000..ca271b56 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_geo_003.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_hue_001.png b/docs/auto_examples/images/sphx_glr_plot_hue_001.png index 7ce70604..c8b1f27e 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_hue_001.png and b/docs/auto_examples/images/sphx_glr_plot_hue_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_impute_001.png b/docs/auto_examples/images/sphx_glr_plot_impute_001.png new file mode 100644 index 00000000..11d6c3c3 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_impute_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_interactive_backend_002.html b/docs/auto_examples/images/sphx_glr_plot_interactive_backend_002.html index 9c74f73c..fb59e2e0 100644 --- a/docs/auto_examples/images/sphx_glr_plot_interactive_backend_002.html +++ b/docs/auto_examples/images/sphx_glr_plot_interactive_backend_002.html @@ -2,6 +2,6 @@
-
+
\ No newline at end of file diff --git a/docs/auto_examples/images/sphx_glr_plot_interactive_backend_002.png b/docs/auto_examples/images/sphx_glr_plot_interactive_backend_002.png index d7e50d54..3e8b865d 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_interactive_backend_002.png and b/docs/auto_examples/images/sphx_glr_plot_interactive_backend_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_labels_001.png b/docs/auto_examples/images/sphx_glr_plot_labels_001.png index 79da5c81..ada748a4 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_labels_001.png and b/docs/auto_examples/images/sphx_glr_plot_labels_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_legend_001.png b/docs/auto_examples/images/sphx_glr_plot_legend_001.png index 1e10ec1b..c8bb1508 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_legend_001.png and b/docs/auto_examples/images/sphx_glr_plot_legend_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_missing_data_001.png b/docs/auto_examples/images/sphx_glr_plot_missing_data_001.png index 4caccb4b..09978742 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_missing_data_001.png and b/docs/auto_examples/images/sphx_glr_plot_missing_data_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_mixture_models_001.png b/docs/auto_examples/images/sphx_glr_plot_mixture_models_001.png index 88b8aa9f..160c9803 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_mixture_models_001.png and b/docs/auto_examples/images/sphx_glr_plot_mixture_models_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_mixture_models_002.png b/docs/auto_examples/images/sphx_glr_plot_mixture_models_002.png index dbf3e539..b8f5e3de 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_mixture_models_002.png and b/docs/auto_examples/images/sphx_glr_plot_mixture_models_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_multicolored_lines_001.png b/docs/auto_examples/images/sphx_glr_plot_multicolored_lines_001.png index 1129bc0f..5bb044e0 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_multicolored_lines_001.png and b/docs/auto_examples/images/sphx_glr_plot_multicolored_lines_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_multicolored_lines_002.png b/docs/auto_examples/images/sphx_glr_plot_multicolored_lines_002.png index a79258bb..30e558e9 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_multicolored_lines_002.png and b/docs/auto_examples/images/sphx_glr_plot_multicolored_lines_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_multiindex_001.png b/docs/auto_examples/images/sphx_glr_plot_multiindex_001.png new file mode 100644 index 00000000..f8ad0012 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_multiindex_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_nested_lists_001.png b/docs/auto_examples/images/sphx_glr_plot_nested_lists_001.png index 2c44f4b5..f83d9d5e 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_nested_lists_001.png and b/docs/auto_examples/images/sphx_glr_plot_nested_lists_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_nested_lists_002.png b/docs/auto_examples/images/sphx_glr_plot_nested_lists_002.png index f34746d2..1b7fa6a4 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_nested_lists_002.png and b/docs/auto_examples/images/sphx_glr_plot_nested_lists_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_normalize_001.png b/docs/auto_examples/images/sphx_glr_plot_normalize_001.png index a082d0ac..3d07e6e4 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_normalize_001.png and b/docs/auto_examples/images/sphx_glr_plot_normalize_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_normalize_002.png b/docs/auto_examples/images/sphx_glr_plot_normalize_002.png index 4f369a77..ca71eadc 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_normalize_002.png and b/docs/auto_examples/images/sphx_glr_plot_normalize_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_normalize_003.png b/docs/auto_examples/images/sphx_glr_plot_normalize_003.png index 1d60a314..de4d3c3b 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_normalize_003.png and b/docs/auto_examples/images/sphx_glr_plot_normalize_003.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_predict_001.png b/docs/auto_examples/images/sphx_glr_plot_predict_001.png new file mode 100644 index 00000000..79fc7d51 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_predict_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_procrustes_001.png b/docs/auto_examples/images/sphx_glr_plot_procrustes_001.png index 3355b166..b94d28f9 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_procrustes_001.png and b/docs/auto_examples/images/sphx_glr_plot_procrustes_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_procrustes_002.png b/docs/auto_examples/images/sphx_glr_plot_procrustes_002.png index 31eea126..ff433a05 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_procrustes_002.png and b/docs/auto_examples/images/sphx_glr_plot_procrustes_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_shape_morph_001.gif b/docs/auto_examples/images/sphx_glr_plot_shape_morph_001.gif new file mode 100644 index 00000000..b9f62f2c Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_shape_morph_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_plot_shape_morph_001.mp4 b/docs/auto_examples/images/sphx_glr_plot_shape_morph_001.mp4 new file mode 100644 index 00000000..0eb20535 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_shape_morph_001.mp4 differ diff --git a/docs/auto_examples/images/sphx_glr_plot_sotus_001.png b/docs/auto_examples/images/sphx_glr_plot_sotus_001.png index 46a9906d..3aa3f403 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_sotus_001.png and b/docs/auto_examples/images/sphx_glr_plot_sotus_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_surface_001.png b/docs/auto_examples/images/sphx_glr_plot_surface_001.png new file mode 100644 index 00000000..f6ddd142 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_surface_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_surface_002.png b/docs/auto_examples/images/sphx_glr_plot_surface_002.png new file mode 100644 index 00000000..52c127ca Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_plot_surface_002.png differ diff --git a/docs/auto_examples/images/sphx_glr_plot_text_001.png b/docs/auto_examples/images/sphx_glr_plot_text_001.png index 79ca83aa..55c762dc 100644 Binary files a/docs/auto_examples/images/sphx_glr_plot_text_001.png and b/docs/auto_examples/images/sphx_glr_plot_text_001.png differ diff --git a/docs/auto_examples/images/sphx_glr_precog_001.gif b/docs/auto_examples/images/sphx_glr_precog_001.gif index 71d5e514..b79489e5 100644 Binary files a/docs/auto_examples/images/sphx_glr_precog_001.gif and b/docs/auto_examples/images/sphx_glr_precog_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_precog_001.mp4 b/docs/auto_examples/images/sphx_glr_precog_001.mp4 index 733389e9..ade8303c 100644 Binary files a/docs/auto_examples/images/sphx_glr_precog_001.mp4 and b/docs/auto_examples/images/sphx_glr_precog_001.mp4 differ diff --git a/docs/auto_examples/images/sphx_glr_save_movie_001.gif b/docs/auto_examples/images/sphx_glr_save_movie_001.gif new file mode 100644 index 00000000..d672b97d Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_save_movie_001.gif differ diff --git a/docs/auto_examples/images/sphx_glr_save_movie_001.mp4 b/docs/auto_examples/images/sphx_glr_save_movie_001.mp4 new file mode 100644 index 00000000..79115c12 Binary files /dev/null and b/docs/auto_examples/images/sphx_glr_save_movie_001.mp4 differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_animate_MDS_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_animate_MDS_thumb.gif index 265f02d4..ec171741 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_animate_MDS_thumb.gif and b/docs/auto_examples/images/thumb/sphx_glr_animate_MDS_thumb.gif differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_animate_plotly_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_animate_plotly_thumb.png index 8851bc24..838a5b35 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_animate_plotly_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_animate_plotly_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_animate_spin_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_animate_spin_thumb.gif index cdb42487..887f8690 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_animate_spin_thumb.gif and b/docs/auto_examples/images/thumb/sphx_glr_animate_spin_thumb.gif differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_animate_surface_morph_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_animate_surface_morph_thumb.gif new file mode 100644 index 00000000..61a5f68d Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_animate_surface_morph_thumb.gif differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_animate_surface_morph_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_animate_surface_morph_thumb.png new file mode 100644 index 00000000..5da657bf Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_animate_surface_morph_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_animate_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_animate_thumb.gif index 065358e1..21fa14b1 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_animate_thumb.gif and b/docs/auto_examples/images/thumb/sphx_glr_animate_thumb.gif differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_animate_trails_mix_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_animate_trails_mix_thumb.gif new file mode 100644 index 00000000..f0aebc61 Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_animate_trails_mix_thumb.gif differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_chemtrails_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_chemtrails_thumb.gif index b44e6dcd..294663ad 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_chemtrails_thumb.gif and b/docs/auto_examples/images/thumb/sphx_glr_chemtrails_thumb.gif differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_2D_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_2D_thumb.png index c943117d..ffacb3fc 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_2D_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_2D_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_PPCA_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_PPCA_thumb.png index 09589850..11221102 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_PPCA_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_PPCA_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_TSNE_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_TSNE_thumb.png index a54c29ce..27b57efe 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_TSNE_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_TSNE_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_UMAP_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_UMAP_thumb.png index 65a54163..cebf7a34 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_UMAP_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_UMAP_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_align_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_align_thumb.png index 12c07d41..91397f01 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_align_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_align_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_basic_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_basic_thumb.png index dee50293..d5aa4c55 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_basic_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_basic_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_clusters2_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_clusters2_thumb.png index 782c0eee..9b98d8e7 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_clusters2_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_clusters2_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_clusters3_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_clusters3_thumb.png index 912fb596..e40a0dbb 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_clusters3_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_clusters3_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_clusters_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_clusters_thumb.png index 93ff268f..85bdcba0 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_clusters_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_clusters_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_colorbar_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_colorbar_thumb.png new file mode 100644 index 00000000..ebcffe50 Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_plot_colorbar_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_corpus_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_corpus_thumb.png index 5a5338c6..d8bf1d10 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_corpus_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_corpus_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_dataframe_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_dataframe_thumb.png index aae5b78b..cef32400 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_dataframe_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_dataframe_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_density_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_density_thumb.png new file mode 100644 index 00000000..a96d3d99 Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_plot_density_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_describe_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_describe_thumb.png index 89302b30..c2e168a8 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_describe_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_describe_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_digits_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_digits_thumb.png index f1c4ead9..027051a9 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_digits_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_digits_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_geo_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_geo_thumb.png index aae5b78b..0002751e 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_geo_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_geo_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_hue_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_hue_thumb.png index ec5a19fe..a10eaf92 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_hue_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_hue_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_impute_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_impute_thumb.png new file mode 100644 index 00000000..a88917ea Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_plot_impute_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_labels_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_labels_thumb.png index 871fbf12..d69473e2 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_labels_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_labels_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_legend_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_legend_thumb.png index 57da9e14..53a541e4 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_legend_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_legend_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_missing_data_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_missing_data_thumb.png index 8a392e35..1661b971 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_missing_data_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_missing_data_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_mixture_models_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_mixture_models_thumb.png index c2331065..eb1ed5d8 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_mixture_models_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_mixture_models_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_multicolored_lines_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_multicolored_lines_thumb.png index 16970944..77cdb0fc 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_multicolored_lines_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_multicolored_lines_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_multiindex_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_multiindex_thumb.png new file mode 100644 index 00000000..ca66c51d Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_plot_multiindex_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_nested_lists_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_nested_lists_thumb.png index 39df3a1d..0fc0d41e 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_nested_lists_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_nested_lists_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_normalize_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_normalize_thumb.png index d30eda91..1bc57b46 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_normalize_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_normalize_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_predict_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_predict_thumb.png new file mode 100644 index 00000000..270d22fc Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_plot_predict_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_procrustes_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_procrustes_thumb.png index 410b76ca..b3ccb717 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_procrustes_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_procrustes_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_shape_morph_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_plot_shape_morph_thumb.gif new file mode 100644 index 00000000..b9f62f2c Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_plot_shape_morph_thumb.gif differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_sotus_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_sotus_thumb.png index 610ea5f2..1bfd289b 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_sotus_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_sotus_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_surface_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_surface_thumb.png new file mode 100644 index 00000000..0dff59cd Binary files /dev/null and b/docs/auto_examples/images/thumb/sphx_glr_plot_surface_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_plot_text_thumb.png b/docs/auto_examples/images/thumb/sphx_glr_plot_text_thumb.png index 0a54a19a..0b6c1d4d 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_plot_text_thumb.png and b/docs/auto_examples/images/thumb/sphx_glr_plot_text_thumb.png differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_precog_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_precog_thumb.gif index ef8d9c39..0928e2c4 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_precog_thumb.gif and b/docs/auto_examples/images/thumb/sphx_glr_precog_thumb.gif differ diff --git a/docs/auto_examples/images/thumb/sphx_glr_save_movie_thumb.gif b/docs/auto_examples/images/thumb/sphx_glr_save_movie_thumb.gif index 199e1ee6..55e8b904 100644 Binary files a/docs/auto_examples/images/thumb/sphx_glr_save_movie_thumb.gif and b/docs/auto_examples/images/thumb/sphx_glr_save_movie_thumb.gif differ diff --git a/docs/auto_examples/index.rst b/docs/auto_examples/index.rst index 2129f60d..c543d18e 100644 --- a/docs/auto_examples/index.rst +++ b/docs/auto_examples/index.rst @@ -87,35 +87,35 @@ Gallery of Examples .. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_plot_legend_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_describe_thumb.png :alt: - :doc:`/auto_examples/plot_legend` + :doc:`/auto_examples/plot_describe` .. raw:: html -
Generating a legend
+
Using describe to evaluate the integrity of your visualization
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_plot_describe_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_legend_thumb.png :alt: - :doc:`/auto_examples/plot_describe` + :doc:`/auto_examples/plot_legend` .. raw:: html -
Using describe to evaluate the integrity of your visualization
+
Generating a legend
@@ -189,120 +189,137 @@ Gallery of Examples .. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_plot_clusters3_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_chemtrails_thumb.png :alt: - :doc:`/auto_examples/plot_clusters3` + :doc:`/auto_examples/chemtrails` .. raw:: html -
Discovering clusters using HDBSCAN
+
Chemtrails
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_plot_align_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_animate_MDS_thumb.png :alt: - :doc:`/auto_examples/plot_align` + :doc:`/auto_examples/animate_MDS` .. raw:: html -
Aligning matrices to a common space
+
Animated trajectory plotted with multidimensional scaling
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_chemtrails_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_animate_spin_thumb.png :alt: - :doc:`/auto_examples/chemtrails` + :doc:`/auto_examples/animate_spin` .. raw:: html -
Chemtrails
+
Create a rotating static plot
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_animate_MDS_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_animate_thumb.png :alt: - :doc:`/auto_examples/animate_MDS` + :doc:`/auto_examples/animate` .. raw:: html -
Animated trajectory plotted with multidimensional scaling
+
Animated plots
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_animate_spin_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_precog_thumb.png :alt: - :doc:`/auto_examples/animate_spin` + :doc:`/auto_examples/precog` .. raw:: html -
Create a rotating static plot
+
Precognition
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_animate_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_align_thumb.png :alt: - :doc:`/auto_examples/animate` + :doc:`/auto_examples/plot_align` .. raw:: html -
Animated plots
+
Aligning matrices to a common space
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_precog_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_clusters3_thumb.png :alt: - :doc:`/auto_examples/precog` + :doc:`/auto_examples/plot_clusters3` .. raw:: html -
Precognition
+
Discovering clusters using HDBSCAN
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_analyze_thumb.png + :alt: + + :doc:`/auto_examples/analyze` + +.. raw:: html + +
Analyze data and then plot
@@ -342,69 +359,69 @@ Gallery of Examples .. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_analyze_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_hue_thumb.png :alt: - :doc:`/auto_examples/analyze` + :doc:`/auto_examples/plot_hue` .. raw:: html -
Analyze data and then plot
+
Grouping data by category
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_plot_procrustes_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_nested_lists_thumb.png :alt: - :doc:`/auto_examples/plot_procrustes` + :doc:`/auto_examples/plot_nested_lists` .. raw:: html -
Aligning two matrices with the procrustes function
+
Nested lists and multilevel styling
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_plot_hue_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_colorbar_thumb.png :alt: - :doc:`/auto_examples/plot_hue` + :doc:`/auto_examples/plot_colorbar` .. raw:: html -
Grouping data by category
+
Colorbars
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_plot_nested_lists_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_procrustes_thumb.png :alt: - :doc:`/auto_examples/plot_nested_lists` + :doc:`/auto_examples/plot_procrustes` .. raw:: html -
Nested lists and multilevel styling
+
Aligning two matrices with the procrustes function
@@ -425,6 +442,23 @@ Gallery of Examples
+.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_save_movie_thumb.png + :alt: + + :doc:`/auto_examples/save_movie` + +.. raw:: html + +
Saving an animation
+
+ + .. raw:: html
@@ -444,7 +478,7 @@ Gallery of Examples .. raw:: html -
+
.. only:: html @@ -512,35 +546,35 @@ Gallery of Examples .. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_plot_geo_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_density_thumb.png :alt: - :doc:`/auto_examples/plot_geo` + :doc:`/auto_examples/plot_density` .. raw:: html -
A DataGeometry object or "geo"
+
Density shading
.. raw:: html -
+
.. only:: html - .. image:: /auto_examples/images/thumb/sphx_glr_save_movie_thumb.png + .. image:: /auto_examples/images/thumb/sphx_glr_plot_surface_thumb.png :alt: - :doc:`/auto_examples/save_movie` + :doc:`/auto_examples/plot_surface` .. raw:: html -
Saving an animation
+
Surfaces around point clouds
@@ -561,6 +595,23 @@ Gallery of Examples
+.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_animate_trails_mix_thumb.gif + :alt: + + :doc:`/auto_examples/animate_trails_mix` + +.. raw:: html + +
Mixing trail styles per dataset
+
+ + .. raw:: html
@@ -580,7 +631,7 @@ Gallery of Examples .. raw:: html -
+
.. only:: html @@ -631,7 +682,24 @@ Gallery of Examples .. raw:: html -
+
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_plot_geo_thumb.png + :alt: + + :doc:`/auto_examples/plot_geo` + +.. raw:: html + +
Working with plot outputs (figures & fitted models)
+
+ + +.. raw:: html + +
.. only:: html @@ -663,6 +731,74 @@ Gallery of Examples
+.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_plot_predict_thumb.png + :alt: + + :doc:`/auto_examples/plot_predict` + +.. raw:: html + +
Forecasting timeseries with predict
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_plot_multiindex_thumb.png + :alt: + + :doc:`/auto_examples/plot_multiindex` + +.. raw:: html + +
MultiIndex DataFrames
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_plot_impute_thumb.png + :alt: + + :doc:`/auto_examples/plot_impute` + +.. raw:: html + +
Imputing missing data: PPCA vs Kalman smoothing
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_plot_shape_morph_thumb.gif + :alt: + + :doc:`/auto_examples/plot_shape_morph` + +.. raw:: html + +
Morphing through the shapes zoo
+
+ + .. raw:: html
@@ -680,6 +816,23 @@ Gallery of Examples
+.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_animate_surface_morph_thumb.png + :alt: + + :doc:`/auto_examples/animate_surface_morph` + +.. raw:: html + +
Morphing hull surfaces through shapes
+
+ + .. thumbnail-parent-div-close .. raw:: html @@ -694,41 +847,50 @@ Gallery of Examples /auto_examples/plot_2D /auto_examples/plot_clusters /auto_examples/plot_dataframe - /auto_examples/plot_legend /auto_examples/plot_describe + /auto_examples/plot_legend /auto_examples/plot_digits /auto_examples/plot_TSNE /auto_examples/explore /auto_examples/plot_UMAP - /auto_examples/plot_clusters3 - /auto_examples/plot_align /auto_examples/chemtrails /auto_examples/animate_MDS /auto_examples/animate_spin /auto_examples/animate /auto_examples/precog + /auto_examples/plot_align + /auto_examples/plot_clusters3 + /auto_examples/analyze /auto_examples/plot_corpus /auto_examples/save_image - /auto_examples/analyze - /auto_examples/plot_procrustes /auto_examples/plot_hue /auto_examples/plot_nested_lists + /auto_examples/plot_colorbar + /auto_examples/plot_procrustes /auto_examples/plot_labels + /auto_examples/save_movie /auto_examples/plot_text /auto_examples/plot_interactive_backend /auto_examples/plot_clusters2 /auto_examples/animate_plotly /auto_examples/plot_multicolored_lines - /auto_examples/plot_geo - /auto_examples/save_movie + /auto_examples/plot_density + /auto_examples/plot_surface /auto_examples/plot_PPCA + /auto_examples/animate_trails_mix /auto_examples/plot_normalize /auto_examples/plot_mixture_models /auto_examples/plot_datasaurus /auto_examples/plot_shapes_zoo + /auto_examples/plot_geo /auto_examples/plot_apply_model /auto_examples/plot_missing_data + /auto_examples/plot_predict + /auto_examples/plot_multiindex + /auto_examples/plot_impute + /auto_examples/plot_shape_morph /auto_examples/plot_sotus + /auto_examples/animate_surface_morph .. only:: html diff --git a/docs/auto_examples/plot_2D.codeobj.json b/docs/auto_examples/plot_2D.codeobj.json index 11d4a30b..fae7d364 100644 --- a/docs/auto_examples/plot_2D.codeobj.json +++ b/docs/auto_examples/plot_2D.codeobj.json @@ -1,37 +1,30 @@ { - "geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -44,7 +37,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/plot_2D.ipynb b/docs/auto_examples/plot_2D.ipynb index 3cb1bc37..83686538 100644 --- a/docs/auto_examples/plot_2D.ipynb +++ b/docs/auto_examples/plot_2D.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# A 2D Plot\n\nA 2D plot can be created by setting ndims=2.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load data\ndata = hyp.load('weights_sample')\n\n# plot\nhyp.plot(data, fmt='.', ndims=2)" + ] + } + ], + "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# A 2D Plot\n\nA 2D plot can be created by setting ndims=2.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load data\ngeo = hyp.load('weights_sample')\n\n# plot\ngeo.plot(fmt='.', ndims=2)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_2D.py b/docs/auto_examples/plot_2D.py index 34fb856f..15dd0878 100644 --- a/docs/auto_examples/plot_2D.py +++ b/docs/auto_examples/plot_2D.py @@ -14,7 +14,7 @@ import hypertools as hyp # load data -geo = hyp.load('weights_sample') +data = hyp.load('weights_sample') # plot -geo.plot(fmt='.', ndims=2) +hyp.plot(data, fmt='.', ndims=2) diff --git a/docs/auto_examples/plot_2D.py.md5 b/docs/auto_examples/plot_2D.py.md5 index 410205bb..ba90d344 100644 --- a/docs/auto_examples/plot_2D.py.md5 +++ b/docs/auto_examples/plot_2D.py.md5 @@ -1 +1 @@ -394fd50c0726101f63746bbfd3d8d613 \ No newline at end of file +2e46f8921b33470a8f173f5ee307699e \ No newline at end of file diff --git a/docs/auto_examples/plot_2D.rst b/docs/auto_examples/plot_2D.rst index 36e4ba22..1db7a084 100644 --- a/docs/auto_examples/plot_2D.rst +++ b/docs/auto_examples/plot_2D.rst @@ -34,20 +34,8 @@ A 2D plot can be created by setting ndims=2. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - /Users/jmanning/hypertools/hypertools/tools/reduce.py:133: UserWarning: Unequal values passed to dims and n_components. Using ndims parameter. - warnings.warn('Unequal values passed to dims and n_components. Using ndims parameter.') - - - - - - - -| .. code-block:: Python @@ -59,15 +47,15 @@ A 2D plot can be created by setting ndims=2. import hypertools as hyp # load data - geo = hyp.load('weights_sample') + data = hyp.load('weights_sample') # plot - geo.plot(fmt='.', ndims=2) + hyp.plot(data, fmt='.', ndims=2) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.043 seconds) + **Total running time of the script:** (0 minutes 0.017 seconds) .. _sphx_glr_download_auto_examples_plot_2D.py: diff --git a/docs/auto_examples/plot_2D.zip b/docs/auto_examples/plot_2D.zip index 916d4144..32230d4b 100644 Binary files a/docs/auto_examples/plot_2D.zip and b/docs/auto_examples/plot_2D.zip differ diff --git a/docs/auto_examples/plot_PPCA.ipynb b/docs/auto_examples/plot_PPCA.ipynb index f8291d6e..4f8ca735 100644 --- a/docs/auto_examples/plot_PPCA.ipynb +++ b/docs/auto_examples/plot_PPCA.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Interpolating missing data with probabalistic PCA\n\nWhen you pass a matrix with with missing data, hypertools will attempt to\nfill in the values using probabalistic principal components analysis (PPCA).\nHere is an example where we generate some synthetic data, remove some of the\nvalues, and then use PPCA to interpolate those missing values. Then, we plot\nboth the original and data with missing values together to see how it performed.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nfrom scipy.linalg import toeplitz\nimport numpy as np\nfrom copy import copy\nimport hypertools as hyp\n\n# simulate data\nK = 10 - toeplitz(np.arange(10))\ndata1 = np.cumsum(np.random.multivariate_normal(np.zeros(10), K, 250), axis=0)\ndata2 = copy(data1)\n\n# simulate missing data\nmissing = .1\ninds = [(i,j) for i in range(data2.shape[0]) for j in range(data2.shape[1])]\nmissing_data = [inds[i] for i in np.random.choice(int(len(inds)), int(len(inds)*missing))]\nfor i,j in missing_data:\n data2[i,j]=np.nan\n\n# plot\nhyp.plot([data1, data2], linestyle=['-',':'], legend=['Original', 'PPCA'])" + ] + } + ], + "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# Interpolating missing data with probabalistic PCA\n\nWhen you pass a matrix with with missing data, hypertools will attempt to\nfill in the values using probabalistic principal components analysis (PPCA).\nHere is an example where we generate some synthetic data, remove some of the\nvalues, and then use PPCA to interpolate those missing values. Then, we plot\nboth the original and data with missing values together to see how it performed.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nfrom scipy.linalg import toeplitz\nimport numpy as np\nfrom copy import copy\nimport hypertools as hyp\n\n# simulate data\nK = 10 - toeplitz(np.arange(10))\ndata1 = np.cumsum(np.random.multivariate_normal(np.zeros(10), K, 250), axis=0)\ndata2 = copy(data1)\n\n# simulate missing data\nmissing = .1\ninds = [(i,j) for i in range(data2.shape[0]) for j in range(data2.shape[1])]\nmissing_data = [inds[i] for i in np.random.choice(int(len(inds)), int(len(inds)*missing))]\nfor i,j in missing_data:\n data2[i,j]=np.nan\n\n# plot\nhyp.plot([data1, data2], linestyle=['-',':'], legend=['Original', 'PPCA'])" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_PPCA.rst b/docs/auto_examples/plot_PPCA.rst index 2dc14e1b..479933ba 100644 --- a/docs/auto_examples/plot_PPCA.rst +++ b/docs/auto_examples/plot_PPCA.rst @@ -42,12 +42,11 @@ both the original and data with missing values together to see how it performed. .. code-block:: none - /Users/jmanning/hypertools/hypertools/tools/format_data.py:140: UserWarning: Missing data: Inexact solution computed with PPCA (see https://github.com/allentran/pca-magic for details) + /Users/jmanning/hypertools/hypertools/tools/format_data.py:131: UserWarning: Missing data: Inexact solution computed with PPCA (see https://github.com/allentran/pca-magic for details) warnings.warn('Missing data: Inexact solution computed with PPCA (see https://github.com/allentran/pca-magic for details)') - /Users/jmanning/hypertools/hypertools/plot/draw.py:90: UserWarning: linestyle is redundantly defined by the 'linestyle' keyword argument and the fmt string "-" (-> linestyle='-'). The keyword argument will take precedence. + /Users/jmanning/hypertools/hypertools/plot/matplotlib_backend.py:102: UserWarning: linestyle is redundantly defined by the 'linestyle' keyword argument and the fmt string "-" (-> linestyle='-'). The keyword argument will take precedence. ax.plot(data[i][:, 0], data[i][:, 1], data[i][:, 2], fmt[i], **ikwargs) - @@ -85,7 +84,7 @@ both the original and data with missing values together to see how it performed. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.036 seconds) + **Total running time of the script:** (0 minutes 0.043 seconds) .. _sphx_glr_download_auto_examples_plot_PPCA.py: diff --git a/docs/auto_examples/plot_PPCA.zip b/docs/auto_examples/plot_PPCA.zip index d11a9f0b..e01e8c4a 100644 Binary files a/docs/auto_examples/plot_PPCA.zip and b/docs/auto_examples/plot_PPCA.zip differ diff --git a/docs/auto_examples/plot_TSNE.ipynb b/docs/auto_examples/plot_TSNE.ipynb index 4c454900..2ac67502 100644 --- a/docs/auto_examples/plot_TSNE.ipynb +++ b/docs/auto_examples/plot_TSNE.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Visualizing the digits dataset using t-SNE\n\nThis example loads in some data from the scikit-learn digits dataset and plots\nit using t-SNE.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\nfrom sklearn import datasets\nimport hypertools as hyp\n\ndigits = datasets.load_digits(n_class=6)\ndata = digits.data\nhue = digits.target.astype('str')\n\nhyp.plot(data, '.', reduce='TSNE', hue=hue, ndims=2)" + ] + } + ], + "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# Visualizing the digits dataset using t-SNE\n\nThis example loads in some data from the scikit-learn digits dataset and plots\nit using t-SNE.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\nfrom sklearn import datasets\nimport hypertools as hyp\n\ndigits = datasets.load_digits(n_class=6)\ndata = digits.data\nhue = digits.target.astype('str')\n\nhyp.plot(data, '.', reduce='TSNE', hue=hue, ndims=2)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_TSNE.rst b/docs/auto_examples/plot_TSNE.rst index a6f0532c..fc0693b2 100644 --- a/docs/auto_examples/plot_TSNE.rst +++ b/docs/auto_examples/plot_TSNE.rst @@ -35,20 +35,8 @@ it using t-SNE. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( - - - - - - - -| .. code-block:: Python @@ -68,7 +56,7 @@ it using t-SNE. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 1.741 seconds) + **Total running time of the script:** (0 minutes 1.528 seconds) .. _sphx_glr_download_auto_examples_plot_TSNE.py: diff --git a/docs/auto_examples/plot_TSNE.zip b/docs/auto_examples/plot_TSNE.zip index 2d34f5a5..29bbc26c 100644 Binary files a/docs/auto_examples/plot_TSNE.zip and b/docs/auto_examples/plot_TSNE.zip differ diff --git a/docs/auto_examples/plot_UMAP.ipynb b/docs/auto_examples/plot_UMAP.ipynb index 8f39af7e..33023d67 100644 --- a/docs/auto_examples/plot_UMAP.ipynb +++ b/docs/auto_examples/plot_UMAP.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Visualizing the digits dataset using UMAP\n\nThis example loads in some data from the scikit-learn digits dataset and plots\nit using UMAP.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser and Leland McInnes\n# License: MIT\n\nfrom sklearn import datasets\nimport hypertools as hyp\n\ndigits = datasets.load_digits(n_class=6)\ndata = digits.data\nhue = digits.target.astype('str')\n\nhyp.plot(data, '.', reduce='UMAP', hue=hue, ndims=2)" + ] + } + ], + "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# Visualizing the digits dataset using UMAP\n\nThis example loads in some data from the scikit-learn digits dataset and plots\nit using UMAP.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser and Leland McInnes\n# License: MIT\n\nfrom sklearn import datasets\nimport hypertools as hyp\n\ndigits = datasets.load_digits(n_class=6)\ndata = digits.data\nhue = digits.target.astype('str')\n\nhyp.plot(data, '.', reduce='UMAP', hue=hue, ndims=2)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_UMAP.rst b/docs/auto_examples/plot_UMAP.rst index 4fd90e6b..ee49b764 100644 --- a/docs/auto_examples/plot_UMAP.rst +++ b/docs/auto_examples/plot_UMAP.rst @@ -35,20 +35,8 @@ it using UMAP. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( - - - - - - - -| .. code-block:: Python @@ -68,7 +56,7 @@ it using UMAP. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 3.472 seconds) + **Total running time of the script:** (0 minutes 7.720 seconds) .. _sphx_glr_download_auto_examples_plot_UMAP.py: diff --git a/docs/auto_examples/plot_UMAP.zip b/docs/auto_examples/plot_UMAP.zip index 1c8d980d..b861a971 100644 Binary files a/docs/auto_examples/plot_UMAP.zip and b/docs/auto_examples/plot_UMAP.zip differ diff --git a/docs/auto_examples/plot_align.ipynb b/docs/auto_examples/plot_align.ipynb index a3a7fd84..f5cd4069 100644 --- a/docs/auto_examples/plot_align.ipynb +++ b/docs/auto_examples/plot_align.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Aligning matrices to a common space\n\nIn this example, we plot the trajectory of multivariate brain activity for\ntwo groups of subjects that have been hyperaligned (Haxby et al, 2011). First,\nwe use the align tool to project all subjects in the list to a common space.\nThen we average the data into two groups, and plot.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ndata = hyp.load('weights')\ndata = hyp.align(data, align='hyper')\n\n# average into two groups\ngroup1 = np.mean(data[:17], 0)\ngroup2 = np.mean(data[18:], 0)\n\n# plot\nhyp.plot([group1[:100, :], group2[:100, :]])" + ] + } + ], + "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# Aligning matrices to a common space\n\nIn this example, we plot the trajectory of multivariate brain activity for\ntwo groups of subjects that have been hyperaligned (Haxby et al, 2011). First,\nwe use the align tool to project all subjects in the list to a common space.\nThen we average the data into two groups, and plot.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ndata = hyp.load('weights').get_data()\ndata = hyp.align(data, align='hyper')\n\n# average into two groups\ngroup1 = np.mean(data[:17], 0)\ngroup2 = np.mean(data[18:], 0)\n\n# plot\nhyp.plot([group1[:100, :], group2[:100, :]])" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_align.py b/docs/auto_examples/plot_align.py index 0080e898..7e982f91 100644 --- a/docs/auto_examples/plot_align.py +++ b/docs/auto_examples/plot_align.py @@ -18,7 +18,7 @@ import numpy as np # load example data -data = hyp.load('weights').get_data() +data = hyp.load('weights') data = hyp.align(data, align='hyper') # average into two groups diff --git a/docs/auto_examples/plot_align.py.md5 b/docs/auto_examples/plot_align.py.md5 index 39e08a64..b56a089c 100644 --- a/docs/auto_examples/plot_align.py.md5 +++ b/docs/auto_examples/plot_align.py.md5 @@ -1 +1 @@ -2c61b6322ebafb7022fc5d02912b224e \ No newline at end of file +a1bbcc55c44052fb4c8717b93654e1bb \ No newline at end of file diff --git a/docs/auto_examples/plot_align.rst b/docs/auto_examples/plot_align.rst index c7766b8d..1f71bba8 100644 --- a/docs/auto_examples/plot_align.rst +++ b/docs/auto_examples/plot_align.rst @@ -37,19 +37,9 @@ Then we average the data into two groups, and plot. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - - - - - - -| - .. code-block:: Python @@ -61,7 +51,7 @@ Then we average the data into two groups, and plot. import numpy as np # load example data - data = hyp.load('weights').get_data() + data = hyp.load('weights') data = hyp.align(data, align='hyper') # average into two groups @@ -74,7 +64,7 @@ Then we average the data into two groups, and plot. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.152 seconds) + **Total running time of the script:** (0 minutes 1.325 seconds) .. _sphx_glr_download_auto_examples_plot_align.py: diff --git a/docs/auto_examples/plot_align.zip b/docs/auto_examples/plot_align.zip index 7e7f4b23..72a061c9 100644 Binary files a/docs/auto_examples/plot_align.zip and b/docs/auto_examples/plot_align.zip differ diff --git a/docs/auto_examples/plot_apply_model.ipynb b/docs/auto_examples/plot_apply_model.ipynb index 63e87d2b..5c99f003 100644 --- a/docs/auto_examples/plot_apply_model.ipynb +++ b/docs/auto_examples/plot_apply_model.ipynb @@ -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# Applying models with apply_model\n\n`hyp.apply_model` is hypertools 1.0's unified model-application core:\ndatasets are stacked, the model is fit ONCE across all of them, and the\nresult is unstacked back to the input's structure -- which is what makes\nembeddings and cluster assignments comparable across datasets. Models can\nbe specified by name, as a dict with parameters, as a scikit-learn style\ninstance, or as a list (pipeline). `return_model=True` hands back the\nfitted model for reuse on held-out data.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\nrng = np.random.default_rng(42)\ndata1 = np.cumsum(rng.standard_normal((100, 10)), axis=0)\ndata2 = np.cumsum(rng.standard_normal((100, 10)), axis=0)\n\n# one PCA fit across both datasets -> shared, comparable embedding\nembedded = hyp.apply_model([data1, data2], 'PCA', ndims=3)\nhyp.plot(embedded, 'o')\n\n# pipelines: PCA to denoise, then TSNE to embed\nembedded = hyp.apply_model([data1, data2],\n [{'model': 'PCA', 'params': {'n_components': 5}},\n {'model': 'TSNE', 'params': {'n_components': 2}}])\nhyp.plot(embedded, 'o')\n\n# reuse a fitted model on held-out data\ntrain, fitted = hyp.apply_model(data1, 'PCA', ndims=3, return_model=True)\nheld_out = fitted.transform(data2)\nprint(held_out.shape)" + ] + } + ], + "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# Applying models with apply_model\n\n`hyp.apply_model` is hypertools 2.0's unified model-application core:\ndatasets are stacked, the model is fit ONCE across all of them, and the\nresult is unstacked back to the input's structure -- which is what makes\nembeddings and cluster assignments comparable across datasets. Models can\nbe specified by name, as a dict with parameters, as a scikit-learn style\ninstance, or as a list (pipeline). `return_model=True` hands back the\nfitted model for reuse on held-out data.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\nrng = np.random.default_rng(42)\ndata1 = np.cumsum(rng.standard_normal((100, 10)), axis=0)\ndata2 = np.cumsum(rng.standard_normal((100, 10)), axis=0)\n\n# one PCA fit across both datasets -> shared, comparable embedding\nembedded = hyp.apply_model([data1, data2], 'PCA', ndims=3)\nhyp.plot(embedded, 'o')\n\n# pipelines: PCA to denoise, then TSNE to embed\nembedded = hyp.apply_model([data1, data2],\n [{'model': 'PCA', 'params': {'n_components': 5}},\n {'model': 'TSNE', 'params': {'n_components': 2}}])\nhyp.plot(embedded, 'o')\n\n# reuse a fitted model on held-out data\ntrain, fitted = hyp.apply_model(data1, 'PCA', ndims=3, return_model=True)\nheld_out = fitted.transform(data2)\nprint(held_out.shape)" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_apply_model.py b/docs/auto_examples/plot_apply_model.py index 66724d59..0a8af30c 100644 --- a/docs/auto_examples/plot_apply_model.py +++ b/docs/auto_examples/plot_apply_model.py @@ -4,7 +4,7 @@ Applying models with apply_model ============================= -`hyp.apply_model` is hypertools 2.0's unified model-application core: +`hyp.apply_model` is hypertools 1.0's unified model-application core: datasets are stacked, the model is fit ONCE across all of them, and the result is unstacked back to the input's structure -- which is what makes embeddings and cluster assignments comparable across datasets. Models can diff --git a/docs/auto_examples/plot_apply_model.py.md5 b/docs/auto_examples/plot_apply_model.py.md5 index 98c564fe..5cfa4f37 100644 --- a/docs/auto_examples/plot_apply_model.py.md5 +++ b/docs/auto_examples/plot_apply_model.py.md5 @@ -1 +1 @@ -304975478ca7c2cfff1570a4c0176475 \ No newline at end of file +fa5d54d98bc76e855eafbb248be27377 \ No newline at end of file diff --git a/docs/auto_examples/plot_apply_model.rst b/docs/auto_examples/plot_apply_model.rst index 59c47ad5..e0208b3c 100644 --- a/docs/auto_examples/plot_apply_model.rst +++ b/docs/auto_examples/plot_apply_model.rst @@ -22,7 +22,7 @@ Applying models with apply_model ============================= -`hyp.apply_model` is hypertools 2.0's unified model-application core: +`hyp.apply_model` is hypertools 1.0's unified model-application core: datasets are stacked, the model is fit ONCE across all of them, and the result is unstacked back to the input's structure -- which is what makes embeddings and cluster assignments comparable across datasets. Models can @@ -96,7 +96,7 @@ fitted model for reuse on held-out data. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.850 seconds) + **Total running time of the script:** (0 minutes 0.611 seconds) .. _sphx_glr_download_auto_examples_plot_apply_model.py: diff --git a/docs/auto_examples/plot_apply_model.zip b/docs/auto_examples/plot_apply_model.zip index af7897d1..dc0c1b49 100644 Binary files a/docs/auto_examples/plot_apply_model.zip and b/docs/auto_examples/plot_apply_model.zip differ diff --git a/docs/auto_examples/plot_basic.codeobj.json b/docs/auto_examples/plot_basic.codeobj.json index 11d4a30b..fae7d364 100644 --- a/docs/auto_examples/plot_basic.codeobj.json +++ b/docs/auto_examples/plot_basic.codeobj.json @@ -1,37 +1,30 @@ { - "geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -44,7 +37,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/plot_basic.ipynb b/docs/auto_examples/plot_basic.ipynb index 819a166b..2d34124d 100644 --- a/docs/auto_examples/plot_basic.ipynb +++ b/docs/auto_examples/plot_basic.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# A basic example\n\nHere is a basic example where we load in some data (a list of arrays - samples\nby features), take the first two arrays in the list and plot them as points\nwith the 'o'. Hypertools can handle all format strings supported by matplotlib.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ndata = hyp.load('weights_sample')\n\n# plot\nhyp.plot(data, fmt='.')" + ] + } + ], + "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# A basic example\n\nHere is a basic example where we load in some data (a list of arrays - samples\nby features), take the first two arrays in the list and plot them as points\nwith the 'o'. Hypertools can handle all format strings supported by matplotlib.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ngeo = hyp.load('weights_sample')\n\n# plot\ngeo.plot(fmt='.')" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_basic.py b/docs/auto_examples/plot_basic.py index 4df8a865..3852d6d6 100644 --- a/docs/auto_examples/plot_basic.py +++ b/docs/auto_examples/plot_basic.py @@ -16,7 +16,7 @@ import hypertools as hyp # load example data -geo = hyp.load('weights_sample') +data = hyp.load('weights_sample') # plot -geo.plot(fmt='.') +hyp.plot(data, fmt='.') diff --git a/docs/auto_examples/plot_basic.py.md5 b/docs/auto_examples/plot_basic.py.md5 index 0932903a..585f5368 100644 --- a/docs/auto_examples/plot_basic.py.md5 +++ b/docs/auto_examples/plot_basic.py.md5 @@ -1 +1 @@ -7835f638304573e94bcf911322b1c100 \ No newline at end of file +c75242df25f174e0a73040fbf5d98502 \ No newline at end of file diff --git a/docs/auto_examples/plot_basic.rst b/docs/auto_examples/plot_basic.rst index 127f7db2..37875fd1 100644 --- a/docs/auto_examples/plot_basic.rst +++ b/docs/auto_examples/plot_basic.rst @@ -35,19 +35,12 @@ with the 'o'. Hypertools can handle all format strings supported by matplotlib. :srcset: /auto_examples/images/sphx_glr_plot_basic_001.png :class: sphx-glr-single-img +.. raw:: html + :file: images/sphx_glr_plot_basic_002.html -.. rst-class:: sphx-glr-script-out - .. code-block:: none - - - - - - -| .. code-block:: Python @@ -59,15 +52,15 @@ with the 'o'. Hypertools can handle all format strings supported by matplotlib. import hypertools as hyp # load example data - geo = hyp.load('weights_sample') + data = hyp.load('weights_sample') # plot - geo.plot(fmt='.') + hyp.plot(data, fmt='.') .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.028 seconds) + **Total running time of the script:** (0 minutes 0.107 seconds) .. _sphx_glr_download_auto_examples_plot_basic.py: diff --git a/docs/auto_examples/plot_basic.zip b/docs/auto_examples/plot_basic.zip index 07d038c2..a4e486f2 100644 Binary files a/docs/auto_examples/plot_basic.zip and b/docs/auto_examples/plot_basic.zip differ diff --git a/docs/auto_examples/plot_clusters.codeobj.json b/docs/auto_examples/plot_clusters.codeobj.json index 11d4a30b..912dd223 100644 --- a/docs/auto_examples/plot_clusters.codeobj.json +++ b/docs/auto_examples/plot_clusters.codeobj.json @@ -1,37 +1,30 @@ { - "geo": [ + "data": [ { "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" + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -44,7 +37,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/plot_clusters.ipynb b/docs/auto_examples/plot_clusters.ipynb index 135e1fc7..a7ad6698 100644 --- a/docs/auto_examples/plot_clusters.ipynb +++ b/docs/auto_examples/plot_clusters.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Discovering clusters\n\nThe `n_clusters` kwarg can be used to discover clusters in your dataset. It\nrelies on scikit-learn's implementation of k-mean clustering to find clusters,\nand then labels the points accordingly. You must set the number of clusters\nyourself.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ndata = hyp.load('mushrooms')\n\n# plot\nhyp.plot(data, n_clusters=10)" + ] + } + ], + "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# Discovering clusters\n\nThe `n_clusters` kwarg can be used to discover clusters in your dataset. It\nrelies on scikit-learn's implementation of k-mean clustering to find clusters,\nand then labels the points accordingly. You must set the number of clusters\nyourself.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ngeo = hyp.load('mushrooms')\n\n# plot\ngeo.plot(n_clusters=10)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_clusters.py b/docs/auto_examples/plot_clusters.py index 1f3ab5cb..fc616e6c 100644 --- a/docs/auto_examples/plot_clusters.py +++ b/docs/auto_examples/plot_clusters.py @@ -17,7 +17,7 @@ import hypertools as hyp # load example data -geo = hyp.load('mushrooms') +data = hyp.load('mushrooms') # plot -geo.plot(n_clusters=10) +hyp.plot(data, n_clusters=10) diff --git a/docs/auto_examples/plot_clusters.py.md5 b/docs/auto_examples/plot_clusters.py.md5 index 0faa619e..cdd55887 100644 --- a/docs/auto_examples/plot_clusters.py.md5 +++ b/docs/auto_examples/plot_clusters.py.md5 @@ -1 +1 @@ -135fd2870dc66caeee8c265aba807dec \ No newline at end of file +67e0cf46a6f9c5973cdc1001e0bab509 \ No newline at end of file diff --git a/docs/auto_examples/plot_clusters.rst b/docs/auto_examples/plot_clusters.rst index bb0f9522..d1e07798 100644 --- a/docs/auto_examples/plot_clusters.rst +++ b/docs/auto_examples/plot_clusters.rst @@ -37,22 +37,8 @@ yourself. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - /Users/jmanning/hypertools/hypertools/plot/plot.py:399: UserWarning: n_clusters overrides hue, ignoring hue. - warnings.warn("n_clusters overrides hue, ignoring hue.") - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( - - - - - - - -| .. code-block:: Python @@ -64,15 +50,15 @@ yourself. import hypertools as hyp # load example data - geo = hyp.load('mushrooms') + data = hyp.load('mushrooms') # plot - geo.plot(n_clusters=10) + hyp.plot(data, n_clusters=10) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.084 seconds) + **Total running time of the script:** (0 minutes 0.172 seconds) .. _sphx_glr_download_auto_examples_plot_clusters.py: diff --git a/docs/auto_examples/plot_clusters.zip b/docs/auto_examples/plot_clusters.zip index e99f6621..a7baf91f 100644 Binary files a/docs/auto_examples/plot_clusters.zip and b/docs/auto_examples/plot_clusters.zip differ diff --git a/docs/auto_examples/plot_clusters2.ipynb b/docs/auto_examples/plot_clusters2.ipynb index cbdc991c..86a42122 100644 --- a/docs/auto_examples/plot_clusters2.ipynb +++ b/docs/auto_examples/plot_clusters2.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Using the cluster function to label clusters\n\nHere is an example where we generate some synthetic data, and then use the\ncluster function to get cluster labels, which we can then pass to the `hue`\nkwarg to color our points by cluster.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\nfrom scipy.stats import multivariate_normal\n\n# simulate clusters\ncluster1 = np.random.multivariate_normal(np.zeros(3), np.eye(3), size=100)\ncluster2 = np.random.multivariate_normal(np.zeros(3)+3, np.eye(3), size=100)\ndata = np.vstack([cluster1, cluster2])\n\n# get cluster labels\ncluster_labels = hyp.cluster(data, n_clusters=2)\n\n# plot\nhyp.plot(data, '.', hue=cluster_labels)" + ] + } + ], + "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# Using the cluster function to label clusters\n\nHere is an example where we generate some synthetic data, and then use the\ncluster function to get cluster labels, which we can then pass to the `hue`\nkwarg to color our points by cluster.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\nfrom scipy.stats import multivariate_normal\n\n# simulate clusters\ncluster1 = np.random.multivariate_normal(np.zeros(3), np.eye(3), size=100)\ncluster2 = np.random.multivariate_normal(np.zeros(3)+3, np.eye(3), size=100)\ndata = np.vstack([cluster1, cluster2])\n\n# get cluster labels\ncluster_labels = hyp.cluster(data, n_clusters=2)\n\n# plot\nhyp.plot(data, '.', hue=cluster_labels)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_clusters2.rst b/docs/auto_examples/plot_clusters2.rst index cfd01ba1..88e3ec16 100644 --- a/docs/auto_examples/plot_clusters2.rst +++ b/docs/auto_examples/plot_clusters2.rst @@ -36,19 +36,9 @@ kwarg to color our points by cluster. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - - - - - - -| - .. code-block:: Python @@ -74,7 +64,7 @@ kwarg to color our points by cluster. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.025 seconds) + **Total running time of the script:** (0 minutes 0.020 seconds) .. _sphx_glr_download_auto_examples_plot_clusters2.py: diff --git a/docs/auto_examples/plot_clusters2.zip b/docs/auto_examples/plot_clusters2.zip index 92926e03..803afd28 100644 Binary files a/docs/auto_examples/plot_clusters2.zip and b/docs/auto_examples/plot_clusters2.zip differ diff --git a/docs/auto_examples/plot_clusters3.codeobj.json b/docs/auto_examples/plot_clusters3.codeobj.json index 11d4a30b..912dd223 100644 --- a/docs/auto_examples/plot_clusters3.codeobj.json +++ b/docs/auto_examples/plot_clusters3.codeobj.json @@ -1,37 +1,30 @@ { - "geo": [ + "data": [ { "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" + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -44,7 +37,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/plot_clusters3.ipynb b/docs/auto_examples/plot_clusters3.ipynb index 87978851..0c0f3b57 100644 --- a/docs/auto_examples/plot_clusters3.ipynb +++ b/docs/auto_examples/plot_clusters3.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Discovering clusters using HDBSCAN\n\nTo make use of HDBSCAN as the clustering algorithm used to discover clusters,\nyou must specify it as the cluster argument. If you wish to specify HDBSCAN\nparameters you will need the dictionary form which includes both the model\nand the params. Since HDBSCAN does not require the number of clusters,\nn_clusters does not need to be set.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser and Leland McInnes\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport pandas as pd\n\n# load example data\ndata = hyp.load('mushrooms')\n\n# plot\nhyp.plot(data, cluster={'model':'HDBSCAN',\n 'params': {'min_samples':5,\n 'min_cluster_size':30}})" + ] + } + ], + "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# Discovering clusters using HDBSCAN\n\nTo make use of HDBSCAN as the clustering algorithm used to discover clusters,\nyou must specify it as the cluster argument. If you wish to specify HDBSCAN\nparameters you will need the dictionary form which includes both the model\nand the params. Since HDBSCAN does not require the number of clusters,\nn_clusters does not need to be set.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser and Leland McInnes\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport pandas as pd\n\n# load example data\ngeo = hyp.load('mushrooms')\n\n# plot\ngeo.plot(cluster={'model':'HDBSCAN',\n 'params': {'min_samples':5,\n 'min_cluster_size':30}})" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_clusters3.py b/docs/auto_examples/plot_clusters3.py index ee9f2ef4..102c637a 100644 --- a/docs/auto_examples/plot_clusters3.py +++ b/docs/auto_examples/plot_clusters3.py @@ -19,9 +19,9 @@ import pandas as pd # load example data -geo = hyp.load('mushrooms') +data = hyp.load('mushrooms') # plot -geo.plot(cluster={'model':'HDBSCAN', +hyp.plot(data, cluster={'model':'HDBSCAN', 'params': {'min_samples':5, 'min_cluster_size':30}}) diff --git a/docs/auto_examples/plot_clusters3.py.md5 b/docs/auto_examples/plot_clusters3.py.md5 index d2e59c9a..5a627a46 100644 --- a/docs/auto_examples/plot_clusters3.py.md5 +++ b/docs/auto_examples/plot_clusters3.py.md5 @@ -1 +1 @@ -f5cd2848d239abb3eebb7a822c2d3451 \ No newline at end of file +caa629255593150e4bf282f5b9ef3573 \ No newline at end of file diff --git a/docs/auto_examples/plot_clusters3.rst b/docs/auto_examples/plot_clusters3.rst index 14a567c4..d5461094 100644 --- a/docs/auto_examples/plot_clusters3.rst +++ b/docs/auto_examples/plot_clusters3.rst @@ -42,12 +42,9 @@ n_clusters does not need to be set. .. code-block:: none - /Users/jmanning/hypertools/hypertools/plot/plot.py:369: UserWarning: cluster overrides hue, ignoring hue. - warnings.warn("cluster overrides hue, ignoring hue.") - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( + /Users/jmanning/hypertools/.venv/lib/python3.12/site-packages/sklearn/cluster/_hdbscan/hdbscan.py:722: FutureWarning: The default value of `copy` will change from False to True in 1.10. Explicitly set a value for `copy` to silence this warning. + warn( - @@ -66,19 +63,17 @@ n_clusters does not need to be set. import pandas as pd # load example data - geo = hyp.load('mushrooms') + data = hyp.load('mushrooms') # plot - geo.plot(cluster={'model':'HDBSCAN', + hyp.plot(data, cluster={'model':'HDBSCAN', 'params': {'min_samples':5, 'min_cluster_size':30}}) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 3.566 seconds) - -**Estimated memory usage:** 378 MB + **Total running time of the script:** (0 minutes 0.329 seconds) .. _sphx_glr_download_auto_examples_plot_clusters3.py: diff --git a/docs/auto_examples/plot_clusters3.zip b/docs/auto_examples/plot_clusters3.zip index dfc9f74a..76911489 100644 Binary files a/docs/auto_examples/plot_clusters3.zip and b/docs/auto_examples/plot_clusters3.zip differ diff --git a/docs/auto_examples/plot_colorbar.codeobj.json b/docs/auto_examples/plot_colorbar.codeobj.json new file mode 100644 index 00000000..9f0fb66d --- /dev/null +++ b/docs/auto_examples/plot_colorbar.codeobj.json @@ -0,0 +1,114 @@ +{ + "data": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "hue": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "np.linspace": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "linspace" + } + ], + "np.random.default_rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_2_1", + "module_short": "_cython_3_2_1", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "default_rng" + } + ], + "rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator" + } + ], + "rng.standard_normal": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator.standard_normal" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator.standard_normal" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator.standard_normal" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/plot_colorbar.ipynb b/docs/auto_examples/plot_colorbar.ipynb new file mode 100644 index 00000000..6b1875cc --- /dev/null +++ b/docs/auto_examples/plot_colorbar.ipynb @@ -0,0 +1,72 @@ +{ + "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# Colorbars\n\nThe `colorbar` kwarg draws a colorbar reflecting whatever color mapping\nis already in use (GH #100). For a continuous `hue`, the colorbar is a\ncontinuous gradient spanning the actual value range. For discrete groups\n(categorical `hue`, `cluster`/`n_clusters`, or a plain list of datasets),\nthe colorbar is segmented into one block per group, labeled the same way\nthe legend would be.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nimport numpy as np\n\nimport hypertools as hyp\n\nrng = np.random.default_rng(2)\ndata = rng.standard_normal((200, 3)).cumsum(axis=0)\n\n# continuous hue: a colorbar spanning the actual value range\nhue = np.linspace(0, 1, len(data))\nhyp.plot(data, '-', hue=hue, colorbar=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Discrete groups (here, k-means clusters) get a segmented colorbar with\none tick/block per group instead of a continuous gradient. A dict lets\nyou set a label or move the colorbar to another side of the figure.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hyp.plot(data, '.', n_clusters=4,\n colorbar={'label': 'cluster', 'location': 'right'})" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_colorbar.py b/docs/auto_examples/plot_colorbar.py new file mode 100644 index 00000000..a3d5d60b --- /dev/null +++ b/docs/auto_examples/plot_colorbar.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +""" +============================= +Colorbars +============================= + +The `colorbar` kwarg draws a colorbar reflecting whatever color mapping +is already in use (GH #100). For a continuous `hue`, the colorbar is a +continuous gradient spanning the actual value range. For discrete groups +(categorical `hue`, `cluster`/`n_clusters`, or a plain list of datasets), +the colorbar is segmented into one block per group, labeled the same way +the legend would be. +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +import numpy as np + +import hypertools as hyp + +rng = np.random.default_rng(2) +data = rng.standard_normal((200, 3)).cumsum(axis=0) + +# continuous hue: a colorbar spanning the actual value range +hue = np.linspace(0, 1, len(data)) +hyp.plot(data, '-', hue=hue, colorbar=True) + +############################################################################### +# Discrete groups (here, k-means clusters) get a segmented colorbar with +# one tick/block per group instead of a continuous gradient. A dict lets +# you set a label or move the colorbar to another side of the figure. + +hyp.plot(data, '.', n_clusters=4, + colorbar={'label': 'cluster', 'location': 'right'}) diff --git a/docs/auto_examples/plot_colorbar.py.md5 b/docs/auto_examples/plot_colorbar.py.md5 new file mode 100644 index 00000000..a7144e79 --- /dev/null +++ b/docs/auto_examples/plot_colorbar.py.md5 @@ -0,0 +1 @@ +086ff1e248050ca24210bf3adc754d3b \ No newline at end of file diff --git a/docs/auto_examples/plot_colorbar.rst b/docs/auto_examples/plot_colorbar.rst new file mode 100644 index 00000000..38556800 --- /dev/null +++ b/docs/auto_examples/plot_colorbar.rst @@ -0,0 +1,117 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/plot_colorbar.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_plot_colorbar.py: + + +============================= +Colorbars +============================= + +The `colorbar` kwarg draws a colorbar reflecting whatever color mapping +is already in use (GH #100). For a continuous `hue`, the colorbar is a +continuous gradient spanning the actual value range. For discrete groups +(categorical `hue`, `cluster`/`n_clusters`, or a plain list of datasets), +the colorbar is segmented into one block per group, labeled the same way +the legend would be. + +.. GENERATED FROM PYTHON SOURCE LINES 14-29 + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + import numpy as np + + import hypertools as hyp + + rng = np.random.default_rng(2) + data = rng.standard_normal((200, 3)).cumsum(axis=0) + + # continuous hue: a colorbar spanning the actual value range + hue = np.linspace(0, 1, len(data)) + hyp.plot(data, '-', hue=hue, colorbar=True) + + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_colorbar_001.png + :alt: plot colorbar + :srcset: /auto_examples/images/sphx_glr_plot_colorbar_001.png + :class: sphx-glr-single-img + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 30-33 + +Discrete groups (here, k-means clusters) get a segmented colorbar with +one tick/block per group instead of a continuous gradient. A dict lets +you set a label or move the colorbar to another side of the figure. + +.. GENERATED FROM PYTHON SOURCE LINES 33-36 + +.. code-block:: Python + + + hyp.plot(data, '.', n_clusters=4, + colorbar={'label': 'cluster', 'location': 'right'}) + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_colorbar_002.png + :alt: plot colorbar + :srcset: /auto_examples/images/sphx_glr_plot_colorbar_002.png + :class: sphx-glr-single-img + + + + + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 0.306 seconds) + + +.. _sphx_glr_download_auto_examples_plot_colorbar.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: plot_colorbar.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: plot_colorbar.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: plot_colorbar.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/plot_colorbar.zip b/docs/auto_examples/plot_colorbar.zip new file mode 100644 index 00000000..6f8dfce0 Binary files /dev/null and b/docs/auto_examples/plot_colorbar.zip differ diff --git a/docs/auto_examples/plot_corpus.ipynb b/docs/auto_examples/plot_corpus.ipynb index 83145745..8327408f 100644 --- a/docs/auto_examples/plot_corpus.ipynb +++ b/docs/auto_examples/plot_corpus.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Defining a custom corpus for plotting text\n\nBy default, the text samples will be transformed into a vector of word counts\nand then modeled using Latent Dirichlet Allocation (# of topics = 100) using a\nmodel fit to a large sample of wikipedia pages. However, you can optionally\npass your own text to fit the semantic model. To do this define corpus as a\nlist of documents (strings). A topic model will be fit on the fly and the text\nwill be plotted.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# load hypertools\nimport hypertools as hyp\n\n# load the data\ntext_samples = ['i like cats alot', 'cats r pretty cool', 'cats are better than dogs',\n 'dogs rule the haus', 'dogs are my jam', 'dogs are a mans best friend',\n 'i haz a cheezeburger?']\n\n# plot it\nhyp.plot(text_samples, 'o', corpus=text_samples)" + ] + } + ], + "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# Defining a custom corpus for plotting text\n\nBy default, the text samples will be transformed into a vector of word counts\nand then modeled using Latent Dirichlet Allocation (# of topics = 100) using a\nmodel fit to a large sample of wikipedia pages. However, you can optionally\npass your own text to fit the semantic model. To do this define corpus as a\nlist of documents (strings). A topic model will be fit on the fly and the text\nwill be plotted.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# load hypertools\nimport hypertools as hyp\n\n# load the data\ntext_samples = ['i like cats alot', 'cats r pretty cool', 'cats are better than dogs',\n 'dogs rule the haus', 'dogs are my jam', 'dogs are a mans best friend',\n 'i haz a cheezeburger?']\n\n# plot it\nhyp.plot(text_samples, 'o', corpus=text_samples)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_corpus.rst b/docs/auto_examples/plot_corpus.rst index 405a63d0..af9c7be9 100644 --- a/docs/auto_examples/plot_corpus.rst +++ b/docs/auto_examples/plot_corpus.rst @@ -39,19 +39,9 @@ will be plotted. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - - - - - - -| - .. code-block:: Python diff --git a/docs/auto_examples/plot_corpus.zip b/docs/auto_examples/plot_corpus.zip index 8bb8b534..9bee01ae 100644 Binary files a/docs/auto_examples/plot_corpus.zip and b/docs/auto_examples/plot_corpus.zip differ diff --git a/docs/auto_examples/plot_dataframe.codeobj.json b/docs/auto_examples/plot_dataframe.codeobj.json index 6c130460..afb72f43 100644 --- a/docs/auto_examples/plot_dataframe.codeobj.json +++ b/docs/auto_examples/plot_dataframe.codeobj.json @@ -1,53 +1,144 @@ { - "geo": [ + "data": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry" + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" + } + ], + "data.head": [ + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame.head" }, { "is_class": false, "is_explicit": false, - "module": "hypertools", - "module_short": "hypertools", - "name": "DataGeometry" - } - ], - "geo.get_data": [ + "module": "pandas.core.generic", + "module_short": "pandas.core.generic", + "name": "NDFrame.head" + }, { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.get_data" + "module": "pandas.core", + "module_short": "pandas.core", + "name": "NDFrame.head" }, { "is_class": false, "is_explicit": false, - "module": "hypertools", - "module_short": "hypertools", - "name": "DataGeometry.get_data" + "module": "pandas", + "module_short": "pandas", + "name": "NDFrame.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.arraylike", + "module_short": "pandas.core.arraylike", + "name": "OpsMixin.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "OpsMixin.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "OpsMixin.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.base", + "module_short": "pandas.core.base", + "name": "PandasObject.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "PandasObject.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "PandasObject.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.indexing", + "module_short": "pandas.core.indexing", + "name": "IndexingMixin.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "IndexingMixin.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "IndexingMixin.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.accessor", + "module_short": "pandas.core.accessor", + "name": "DirNamesMixin.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "DirNamesMixin.head" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DirNamesMixin.head" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -60,7 +151,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/plot_dataframe.ipynb b/docs/auto_examples/plot_dataframe.ipynb index a5c70cf6..b01f1969 100644 --- a/docs/auto_examples/plot_dataframe.ipynb +++ b/docs/auto_examples/plot_dataframe.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Plotting a Pandas Dataframe\n\nHypertools supports single-index Pandas Dataframes as input. In this example, we\nplot the mushrooms dataset from the kaggle database. This is a dataset of text\nfeatures describing different attributes of a mushroom. Dataframes that contain\ncolumns with text are converted into binary feature vectors representing the\npresence or absences of the feature (see Pandas.Dataframe.get_dummies for more).\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ndata = hyp.load('mushrooms')\n\nprint(data.head())\n\n# plot\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# Plotting a Pandas Dataframe\n\nHypertools supports single-index Pandas Dataframes as input. In this example, we\nplot the mushrooms dataset from the kaggle database. This is a dataset of text\nfeatures describing different attributes of a mushroom. Dataframes that contain\ncolumns with text are converted into binary feature vectors representing the\npresence or absences of the feature (see Pandas.Dataframe.get_dummies for more).\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ngeo = hyp.load('mushrooms')\n\nprint(geo.get_data().head())\n\n# plot\ngeo.plot()" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_dataframe.py b/docs/auto_examples/plot_dataframe.py index b2a42a7d..feec68d1 100644 --- a/docs/auto_examples/plot_dataframe.py +++ b/docs/auto_examples/plot_dataframe.py @@ -18,9 +18,9 @@ import hypertools as hyp # load example data -geo = hyp.load('mushrooms') +data = hyp.load('mushrooms') -print(geo.get_data().head()) +print(data.head()) # plot -geo.plot() +hyp.plot(data) diff --git a/docs/auto_examples/plot_dataframe.py.md5 b/docs/auto_examples/plot_dataframe.py.md5 index 13019343..027b3cfe 100644 --- a/docs/auto_examples/plot_dataframe.py.md5 +++ b/docs/auto_examples/plot_dataframe.py.md5 @@ -1 +1 @@ -4d3fd72aa3d9e1ce4a44f158a67f98ad \ No newline at end of file +df2335d630ebb54b43ed199b09107abb \ No newline at end of file diff --git a/docs/auto_examples/plot_dataframe.rst b/docs/auto_examples/plot_dataframe.rst index 8dabbb99..2b60676c 100644 --- a/docs/auto_examples/plot_dataframe.rst +++ b/docs/auto_examples/plot_dataframe.rst @@ -50,10 +50,7 @@ presence or absences of the feature (see Pandas.Dataframe.get_dummies for more). 4 f g x ... s w p [5 rows x 22 columns] - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( - @@ -71,17 +68,17 @@ presence or absences of the feature (see Pandas.Dataframe.get_dummies for more). import hypertools as hyp # load example data - geo = hyp.load('mushrooms') + data = hyp.load('mushrooms') - print(geo.get_data().head()) + print(data.head()) # plot - geo.plot() + hyp.plot(data) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.042 seconds) + **Total running time of the script:** (0 minutes 0.116 seconds) .. _sphx_glr_download_auto_examples_plot_dataframe.py: diff --git a/docs/auto_examples/plot_dataframe.zip b/docs/auto_examples/plot_dataframe.zip index b12d58a9..9ee2ed4e 100644 Binary files a/docs/auto_examples/plot_dataframe.zip and b/docs/auto_examples/plot_dataframe.zip differ diff --git a/docs/auto_examples/plot_datasaurus.ipynb b/docs/auto_examples/plot_datasaurus.ipynb index cfc5498e..3ea82b5d 100644 --- a/docs/auto_examples/plot_datasaurus.ipynb +++ b/docs/auto_examples/plot_datasaurus.ipynb @@ -8,7 +8,7 @@ }, "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" + "# 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" ] }, { diff --git a/docs/auto_examples/plot_datasaurus.rst b/docs/auto_examples/plot_datasaurus.rst index 0b76ab4c..15b36046 100644 --- a/docs/auto_examples/plot_datasaurus.rst +++ b/docs/auto_examples/plot_datasaurus.rst @@ -101,7 +101,7 @@ it always pays to visualize your data. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.835 seconds) + **Total running time of the script:** (0 minutes 0.753 seconds) .. _sphx_glr_download_auto_examples_plot_datasaurus.py: diff --git a/docs/auto_examples/plot_datasaurus.zip b/docs/auto_examples/plot_datasaurus.zip index 9ff04910..8c48d6c2 100644 Binary files a/docs/auto_examples/plot_datasaurus.zip and b/docs/auto_examples/plot_datasaurus.zip differ diff --git a/docs/auto_examples/plot_density.codeobj.json b/docs/auto_examples/plot_density.codeobj.json new file mode 100644 index 00000000..ce2bc712 --- /dev/null +++ b/docs/auto_examples/plot_density.codeobj.json @@ -0,0 +1,116 @@ +{ + "cluster_a_2d": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "cluster_a_3d": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "cluster_b_2d": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "cluster_b_3d": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "np.random.default_rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_2_1", + "module_short": "_cython_3_2_1", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "default_rng" + } + ], + "rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator" + } + ], + "rng.standard_normal": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator.standard_normal" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator.standard_normal" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator.standard_normal" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/plot_density.ipynb b/docs/auto_examples/plot_density.ipynb new file mode 100644 index 00000000..d29659ba --- /dev/null +++ b/docs/auto_examples/plot_density.ipynb @@ -0,0 +1,90 @@ +{ + "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# Density shading\n\nThe `density` kwarg overlays a subtle KDE (kernel density estimate) \"glow\"\nbehind the data: a 2D alpha-ramped heatmap, or a 3D volumetric cloud,\nshowing where each dataset's points are concentrated (GH #108, #191).\nDensity shading is OFF by default (`density=None`) -- pass `density=True`\nfor the defaults, or a dict to override `alpha`/`levels`/`grid`/`per_group`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nimport numpy as np\n\nimport hypertools as hyp\n\nrng = np.random.default_rng(1)\n\n# two 2D clusters\ncluster_a_2d = rng.standard_normal((200, 2)) * 0.6\ncluster_b_2d = rng.standard_normal((200, 2)) * 0.6 + [4, 0]\n\nhyp.plot([cluster_a_2d, cluster_b_2d], '.', density=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The same kwarg works in 3D, where it renders as a translucent volumetric\ncloud instead of a 2D heatmap.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cluster_a_3d = rng.standard_normal((200, 3)) * 0.6\ncluster_b_3d = rng.standard_normal((200, 3)) * 0.6 + [4, 0, 0]\n\nhyp.plot([cluster_a_3d, cluster_b_3d], '.', density=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A dict lets you turn up the glow (higher `alpha`, more contour `levels`)\nfor a more prominent effect -- but by default the density stays subtle\nso the actual data points remain the dominant visual element.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hyp.plot([cluster_a_2d, cluster_b_2d], '.',\n density={'alpha': 0.4, 'levels': 5})" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_density.py b/docs/auto_examples/plot_density.py new file mode 100644 index 00000000..ece6e907 --- /dev/null +++ b/docs/auto_examples/plot_density.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +""" +============================= +Density shading +============================= + +The `density` kwarg overlays a subtle KDE (kernel density estimate) "glow" +behind the data: a 2D alpha-ramped heatmap, or a 3D volumetric cloud, +showing where each dataset's points are concentrated (GH #108, #191). +Density shading is OFF by default (`density=None`) -- pass `density=True` +for the defaults, or a dict to override `alpha`/`levels`/`grid`/`per_group`. +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +import numpy as np + +import hypertools as hyp + +rng = np.random.default_rng(1) + +# two 2D clusters +cluster_a_2d = rng.standard_normal((200, 2)) * 0.6 +cluster_b_2d = rng.standard_normal((200, 2)) * 0.6 + [4, 0] + +hyp.plot([cluster_a_2d, cluster_b_2d], '.', density=True) + +############################################################################### +# The same kwarg works in 3D, where it renders as a translucent volumetric +# cloud instead of a 2D heatmap. + +cluster_a_3d = rng.standard_normal((200, 3)) * 0.6 +cluster_b_3d = rng.standard_normal((200, 3)) * 0.6 + [4, 0, 0] + +hyp.plot([cluster_a_3d, cluster_b_3d], '.', density=True) + +############################################################################### +# A dict lets you turn up the glow (higher `alpha`, more contour `levels`) +# for a more prominent effect -- but by default the density stays subtle +# so the actual data points remain the dominant visual element. + +hyp.plot([cluster_a_2d, cluster_b_2d], '.', + density={'alpha': 0.4, 'levels': 5}) diff --git a/docs/auto_examples/plot_density.py.md5 b/docs/auto_examples/plot_density.py.md5 new file mode 100644 index 00000000..25eb52be --- /dev/null +++ b/docs/auto_examples/plot_density.py.md5 @@ -0,0 +1 @@ +80dffbe85c1035599f95b040a4208176 \ No newline at end of file diff --git a/docs/auto_examples/plot_density.rst b/docs/auto_examples/plot_density.rst new file mode 100644 index 00000000..aae259e0 --- /dev/null +++ b/docs/auto_examples/plot_density.rst @@ -0,0 +1,144 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/plot_density.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_plot_density.py: + + +============================= +Density shading +============================= + +The `density` kwarg overlays a subtle KDE (kernel density estimate) "glow" +behind the data: a 2D alpha-ramped heatmap, or a 3D volumetric cloud, +showing where each dataset's points are concentrated (GH #108, #191). +Density shading is OFF by default (`density=None`) -- pass `density=True` +for the defaults, or a dict to override `alpha`/`levels`/`grid`/`per_group`. + +.. GENERATED FROM PYTHON SOURCE LINES 13-29 + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + import numpy as np + + import hypertools as hyp + + rng = np.random.default_rng(1) + + # two 2D clusters + cluster_a_2d = rng.standard_normal((200, 2)) * 0.6 + cluster_b_2d = rng.standard_normal((200, 2)) * 0.6 + [4, 0] + + hyp.plot([cluster_a_2d, cluster_b_2d], '.', density=True) + + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_density_001.png + :alt: plot density + :srcset: /auto_examples/images/sphx_glr_plot_density_001.png + :class: sphx-glr-single-img + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 30-32 + +The same kwarg works in 3D, where it renders as a translucent volumetric +cloud instead of a 2D heatmap. + +.. GENERATED FROM PYTHON SOURCE LINES 32-38 + +.. code-block:: Python + + + cluster_a_3d = rng.standard_normal((200, 3)) * 0.6 + cluster_b_3d = rng.standard_normal((200, 3)) * 0.6 + [4, 0, 0] + + hyp.plot([cluster_a_3d, cluster_b_3d], '.', density=True) + + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_density_002.png + :alt: plot density + :srcset: /auto_examples/images/sphx_glr_plot_density_002.png + :class: sphx-glr-single-img + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 39-42 + +A dict lets you turn up the glow (higher `alpha`, more contour `levels`) +for a more prominent effect -- but by default the density stays subtle +so the actual data points remain the dominant visual element. + +.. GENERATED FROM PYTHON SOURCE LINES 42-45 + +.. code-block:: Python + + + hyp.plot([cluster_a_2d, cluster_b_2d], '.', + density={'alpha': 0.4, 'levels': 5}) + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_density_003.png + :alt: plot density + :srcset: /auto_examples/images/sphx_glr_plot_density_003.png + :class: sphx-glr-single-img + + + + + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 1.863 seconds) + + +.. _sphx_glr_download_auto_examples_plot_density.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: plot_density.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: plot_density.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: plot_density.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/plot_density.zip b/docs/auto_examples/plot_density.zip new file mode 100644 index 00000000..afdfa3ab Binary files /dev/null and b/docs/auto_examples/plot_density.zip differ diff --git a/docs/auto_examples/plot_describe.codeobj.json b/docs/auto_examples/plot_describe.codeobj.json index a29c15cb..870b0abd 100644 --- a/docs/auto_examples/plot_describe.codeobj.json +++ b/docs/auto_examples/plot_describe.codeobj.json @@ -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.describe": [ { "is_class": false, diff --git a/docs/auto_examples/plot_describe.ipynb b/docs/auto_examples/plot_describe.ipynb index dce5d88e..848ecbd3 100644 --- a/docs/auto_examples/plot_describe.ipynb +++ b/docs/auto_examples/plot_describe.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Using describe to evaluate the integrity of your visualization\n\nThe downside to using dimensionality reduction to visualize your data is that\nsome variance will likely be removed. To help get a sense for the integrity of your low\ndimensional visualizations, we built the `describe` function, which computes\nthe covariance (samples by samples) of both the raw and reduced datasets, and\nplots their correlation.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ndata = hyp.load('weights_sample')\n\n# plot\nhyp.describe(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# Using describe to evaluate the integrity of your visualization\n\nThe downside to using dimensionality reduction to visualize your data is that\nsome variance will likely be removed. To help get a sense for the integrity of your low\ndimensional visualizations, we built the `describe` function, which computes\nthe covariance (samples by samples) of both the raw and reduced datasets, and\nplots their correlation.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ngeo = hyp.load('weights_sample')\ndata = geo.get_data()\n\n# plot\nhyp.describe(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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_describe.py b/docs/auto_examples/plot_describe.py index 0efd2de4..a3a0af33 100644 --- a/docs/auto_examples/plot_describe.py +++ b/docs/auto_examples/plot_describe.py @@ -19,8 +19,7 @@ import numpy as np # load example data -geo = hyp.load('weights_sample') -data = geo.get_data() +data = hyp.load('weights_sample') # plot hyp.describe(data) diff --git a/docs/auto_examples/plot_describe.py.md5 b/docs/auto_examples/plot_describe.py.md5 index 71a61bee..dcb9d476 100644 --- a/docs/auto_examples/plot_describe.py.md5 +++ b/docs/auto_examples/plot_describe.py.md5 @@ -1 +1 @@ -43d9778a74e62ca9eeb9d6d98dce95d4 \ No newline at end of file +4d3a6652554401bfa1f7ab7c31571056 \ No newline at end of file diff --git a/docs/auto_examples/plot_describe.rst b/docs/auto_examples/plot_describe.rst index 040520c4..ec4599be 100644 --- a/docs/auto_examples/plot_describe.rst +++ b/docs/auto_examples/plot_describe.rst @@ -28,7 +28,7 @@ dimensional visualizations, we built the `describe` function, which computes the covariance (samples by samples) of both the raw and reduced datasets, and plots their correlation. -.. GENERATED FROM PYTHON SOURCE LINES 13-27 +.. GENERATED FROM PYTHON SOURCE LINES 13-26 @@ -42,10 +42,9 @@ plots their correlation. .. code-block:: none - /Users/jmanning/hypertools/hypertools/tools/describe.py:59: UserWarning: When input data is large, this computation can take a long time. + /Users/jmanning/hypertools/hypertools/reduce/describe.py:57: UserWarning: When input data is large, this computation can take a long time. warnings.warn('When input data is large, this computation can take a long time.') - {'average': [np.float64(0.7507899225056418), np.float64(0.832263231292898), np.float64(0.8560561010765376), np.float64(0.8846641566829818), np.float64(0.8987181470102683), np.float64(0.9113677940028716), np.float64(0.922080745902193), np.float64(0.9326917121927507), np.float64(0.9409394567666949), np.float64(0.9453460938146611), np.float64(0.9502954731418026), np.float64(0.9573804379634785), np.float64(0.9597513103274008), np.float64(0.9655319741695906), np.float64(0.9701104008586214), np.float64(0.972595512602342), np.float64(0.9749674714082631), np.float64(0.9788037471202327), np.float64(0.9805874349380063), np.float64(0.9821113616685679), np.float64(0.9840583512981103), np.float64(0.985036053104546), np.float64(0.9864140507838837), np.float64(0.9874306818006509), np.float64(0.9881835375802235), np.float64(0.9887848994691469), np.float64(0.9895234228993935), np.float64(0.990303869585006), np.float64(0.990764344350108), np.float64(0.9915194588795435), np.float64(0.9920775337493973), np.float64(0.9926724018126926), np.float64(0.9932594209021803), np.float64(0.9937112945575762), np.float64(0.994122787681099), np.float64(0.9945137098254105), np.float64(0.9948905766902126), np.float64(0.9951462790398564), np.float64(0.9955618403321056), np.float64(0.9958763186228886), np.float64(0.9961647264499769), np.float64(0.9964919778835198), np.float64(0.9967379856535533), np.float64(0.9969642703700793), np.float64(0.9971222786481708), np.float64(0.9972828121346212), np.float64(0.9975317882951824), np.float64(0.9977209634674977), np.float64(0.997863045308259), np.float64(0.9979875074813053), np.float64(0.998105185538592), np.float64(0.9982413853063511), np.float64(0.9984071440082657), np.float64(0.9984779412925874), np.float64(0.9985910162841581), np.float64(0.9986932502326327), np.float64(0.9987473496028), np.float64(0.9988019997204483), np.float64(0.9988882294551579), np.float64(0.9989524880612295), np.float64(0.9990376799941303), np.float64(0.9991048275234233), np.float64(0.9991755628811374), np.float64(0.9992403948360368), np.float64(0.9993086002646604), np.float64(0.9993733745850013), np.float64(0.9994239601131234), np.float64(0.999483760491832), np.float64(0.9995211897298233), np.float64(0.9995585024705079), np.float64(0.9995841550139183), np.float64(0.9996261261172646), np.float64(0.9996532593566665), np.float64(0.9996858063625902), np.float64(0.9997079144840813), np.float64(0.999728634959629), np.float64(0.9997532548714124), np.float64(0.9997743023148623), np.float64(0.9997932169641308), np.float64(0.9998131143529101), np.float64(0.9998300976114054), np.float64(0.999847864362283), np.float64(0.9998631024835527), np.float64(0.999877528001374), np.float64(0.9998890921648634), np.float64(0.9999080239949197), np.float64(0.9999145039930262), np.float64(0.9999263397734935), np.float64(0.9999379645055295), np.float64(0.9999494931748883), np.float64(0.9999582279491676), np.float64(0.9999659710878028), np.float64(0.9999733387736895), np.float64(0.9999810060753579), np.float64(0.9999852371111638), np.float64(0.9999896899895485), np.float64(0.99999356794691), np.float64(0.9999973294587002)], 'individual': [[np.float64(0.7316676755832998), np.float64(0.8047902246450398), np.float64(0.8610221662594029), np.float64(0.8939543180106683), np.float64(0.9204224280899661), np.float64(0.9398873978281411), np.float64(0.9499635906322419), np.float64(0.9601152109811097), np.float64(0.9670075526515582), np.float64(0.9715012934560515), np.float64(0.9751471764599895), np.float64(0.9800984843871343), np.float64(0.983022017656794), np.float64(0.9856250998634799), np.float64(0.9876489097922486), np.float64(0.9889607764485375), np.float64(0.9903272619645859), np.float64(0.9915639085147554), np.float64(0.9923758367174669), np.float64(0.9931772467617737), np.float64(0.994076433189852), np.float64(0.9948519624302499), np.float64(0.9953599643476314), np.float64(0.9958223350351841), np.float64(0.9961707087166287), np.float64(0.9965103199624445), np.float64(0.9968267481180828), np.float64(0.99717521656962), np.float64(0.9974960160050115), np.float64(0.9976925256993522), np.float64(0.997840142465903), np.float64(0.998065899439824), np.float64(0.9981821280158595), np.float64(0.9983413294483411), np.float64(0.998503907898576), np.float64(0.9986454430819005), np.float64(0.9987791974440936), np.float64(0.9988945807166032), np.float64(0.999017807118273), np.float64(0.9990539955172137), np.float64(0.999130606080785), np.float64(0.9992006666228089), np.float64(0.9992600281103953), np.float64(0.9993246571298725), np.float64(0.9993769594466462), np.float64(0.9994177795069341), np.float64(0.9994662430062661), np.float64(0.9995038553171209), np.float64(0.9995408951432552), np.float64(0.999580258423413), np.float64(0.9996122639130557), np.float64(0.9996413400749304), np.float64(0.999668782880193), np.float64(0.9996902401021559), np.float64(0.9997134336314419), np.float64(0.9997343203747313), np.float64(0.9997545278335644), np.float64(0.999774664397246), np.float64(0.9997919931471978), np.float64(0.9998118058301695), np.float64(0.9998256330628089), np.float64(0.9998379060958333), np.float64(0.9998524562256903), np.float64(0.9998676681496248), np.float64(0.9998798981308057), np.float64(0.9998882938981374), np.float64(0.9998987616443639), np.float64(0.9999061001644166), np.float64(0.9999133481697391), np.float64(0.9999222248574716), np.float64(0.9999303341885004), np.float64(0.9999360632686021), np.float64(0.9999420962834986), np.float64(0.9999470430728798), np.float64(0.9999507539902304), np.float64(0.9999562529840238), np.float64(0.9999599753124889), np.float64(0.9999636810472903), np.float64(0.9999672397871245), np.float64(0.9999709492512253), np.float64(0.999974218327972), np.float64(0.9999769340479967), np.float64(0.9999806774276633), np.float64(0.9999832483758022), np.float64(0.9999853582440479), np.float64(0.99998729491008), np.float64(0.9999895437697047), np.float64(0.9999910641382344), np.float64(0.9999924776754278), np.float64(0.9999938220959388), np.float64(0.9999949316524841), np.float64(0.9999958714459064), np.float64(0.9999967548687161), np.float64(0.9999975291830758), np.float64(0.9999982000046117), np.float64(0.9999988499967556), np.float64(0.9999993128893618), np.float64(0.9999997192773086)], [np.float64(0.8292438602749985), np.float64(0.8758184409932503), np.float64(0.9067934526472866), np.float64(0.9259656190071319), np.float64(0.942073187243484), np.float64(0.951214519035444), np.float64(0.9570650558932468), np.float64(0.9633780868198464), np.float64(0.9714308854231074), np.float64(0.9752781692317325), np.float64(0.978932564552484), np.float64(0.9817467215504938), np.float64(0.9857883671145458), np.float64(0.9876689903647391), np.float64(0.9904337704501165), np.float64(0.9919459000188977), np.float64(0.9928461783711473), np.float64(0.9936886382894367), np.float64(0.9944200956599736), np.float64(0.9952875343913743), np.float64(0.9959074731070796), np.float64(0.9964615923667816), np.float64(0.9968778608138695), np.float64(0.9971191121614968), np.float64(0.9975093377615177), np.float64(0.9977408095461702), np.float64(0.9979680456161178), np.float64(0.9981936174327932), np.float64(0.998379673261344), np.float64(0.9985261628442884), np.float64(0.9986447801988746), np.float64(0.9987917615271997), np.float64(0.9988496487987125), np.float64(0.9989191076075778), np.float64(0.9990207232256726), np.float64(0.9991005934865769), np.float64(0.9991830248942302), np.float64(0.9992372533726739), np.float64(0.9993253721446809), np.float64(0.9993956707542283), np.float64(0.999451862341154), np.float64(0.9995021738271415), np.float64(0.999558963162659), np.float64(0.9995929508671787), np.float64(0.999623188698795), np.float64(0.999654670911951), np.float64(0.9996820847847332), np.float64(0.9997038169858541), np.float64(0.9997270136454708), np.float64(0.9997482415150167), np.float64(0.999767054631429), np.float64(0.9997854889015603), np.float64(0.999803383419449), np.float64(0.9998255744151787), np.float64(0.9998357959437765), np.float64(0.9998503883556485), np.float64(0.9998600586280496), np.float64(0.9998769367976301), np.float64(0.999884809194655), np.float64(0.9998946209507439), np.float64(0.9999021406402985), np.float64(0.99991041237218), np.float64(0.9999172244542718), np.float64(0.999924203660681), np.float64(0.9999305835965371), np.float64(0.999936328029774), np.float64(0.999943849779996), np.float64(0.9999493356875289), np.float64(0.9999534206328298), np.float64(0.9999576772812881), np.float64(0.9999618574953387), np.float64(0.9999656517833726), np.float64(0.9999679021676047), np.float64(0.999971647135097), np.float64(0.9999741625137892), np.float64(0.9999769929187005), np.float64(0.9999788425681302), np.float64(0.9999804936645644), np.float64(0.9999830494007972), np.float64(0.999985032345838), np.float64(0.9999866915120658), np.float64(0.9999883242863529), np.float64(0.9999898862912117), np.float64(0.9999914870519799), np.float64(0.9999928591587128), np.float64(0.9999940647938583), np.float64(0.999995091059735), np.float64(0.999995871393949), np.float64(0.999996510149888), np.float64(0.9999970870102102), np.float64(0.9999975349647974), np.float64(0.9999979260588152), np.float64(0.9999983469996618), np.float64(0.9999987743197593), np.float64(0.9999990552728908), np.float64(0.9999993526471845), np.float64(0.9999996086620557), np.float64(0.9999998333030533)], [np.float64(0.7814312820629149), np.float64(0.869714135690073), np.float64(0.8981478838499388), np.float64(0.9187066206199388), np.float64(0.9342665964498112), np.float64(0.9445385290425816), np.float64(0.9556185658863283), np.float64(0.9608551478729129), np.float64(0.9694791004192814), np.float64(0.9753089227404554), np.float64(0.9780846205131528), np.float64(0.980975089469936), np.float64(0.9830298366067439), np.float64(0.9847863085956594), np.float64(0.9861091173450075), np.float64(0.9877966632849786), np.float64(0.9889325185307938), np.float64(0.9902868226875589), np.float64(0.991168567643791), np.float64(0.9919697174587281), np.float64(0.9928303647669134), np.float64(0.9934986490984041), np.float64(0.9940830962044984), np.float64(0.9947131535695707), np.float64(0.9951920597526098), np.float64(0.9956531507240616), np.float64(0.996016115241972), np.float64(0.9962884051635537), np.float64(0.9965221216718896), np.float64(0.9967862470250315), np.float64(0.9970272639778295), np.float64(0.9972451318451573), np.float64(0.9974303764455946), np.float64(0.9976405479979787), np.float64(0.997798227416454), np.float64(0.997952345714619), np.float64(0.9981349414753018), np.float64(0.9982737029498417), np.float64(0.9984025647095709), np.float64(0.998527669994581), np.float64(0.9986676911349925), np.float64(0.9987725169469507), np.float64(0.9988881192208277), np.float64(0.9989661302664988), np.float64(0.9990403563000665), np.float64(0.9991116652710924), np.float64(0.9991778571208384), np.float64(0.9992420550682666), np.float64(0.9993063948312109), np.float64(0.9993601072602178), np.float64(0.999402684320785), np.float64(0.999441610093296), np.float64(0.9994856564259109), np.float64(0.9995235877653231), np.float64(0.999553985410092), np.float64(0.9995883332271516), np.float64(0.9996188930747526), np.float64(0.9996481230159835), np.float64(0.9996667226384328), np.float64(0.9996926625354391), np.float64(0.9997188670426814), np.float64(0.9997391361612596), np.float64(0.9997557207778042), np.float64(0.9997734601272308), np.float64(0.9997958413130001), np.float64(0.9998148653304679), np.float64(0.9998265268536892), np.float64(0.9998408614275934), np.float64(0.999854205531985), np.float64(0.9998654139182789), np.float64(0.9998750743800489), np.float64(0.9998853083086026), np.float64(0.9998965651536553), np.float64(0.9999041896190668), np.float64(0.9999122331395102), np.float64(0.999919986814852), np.float64(0.9999295129941465), np.float64(0.9999376138926692), np.float64(0.9999444912819029), np.float64(0.9999503505403444), np.float64(0.9999573805362316), np.float64(0.9999617068615837), np.float64(0.9999661059584459), np.float64(0.9999701934927958), np.float64(0.9999750944698904), np.float64(0.9999788117009765), np.float64(0.9999818803592101), np.float64(0.9999850631808526), np.float64(0.9999879457766536), np.float64(0.9999897717801576), np.float64(0.9999917517060078), np.float64(0.9999930531703289), np.float64(0.9999945625645905), np.float64(0.9999958571955115), np.float64(0.9999972560648394), np.float64(0.9999979575552587), np.float64(0.9999987413772862), np.float64(0.9999994866095239)]]} @@ -64,8 +63,7 @@ plots their correlation. import numpy as np # load example data - geo = hyp.load('weights_sample') - data = geo.get_data() + data = hyp.load('weights_sample') # plot hyp.describe(data) @@ -73,7 +71,7 @@ plots their correlation. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 3.708 seconds) + **Total running time of the script:** (0 minutes 3.024 seconds) .. _sphx_glr_download_auto_examples_plot_describe.py: diff --git a/docs/auto_examples/plot_describe.zip b/docs/auto_examples/plot_describe.zip index c59c747d..efc22eff 100644 Binary files a/docs/auto_examples/plot_describe.zip and b/docs/auto_examples/plot_describe.zip differ diff --git a/docs/auto_examples/plot_digits.ipynb b/docs/auto_examples/plot_digits.ipynb index 81ee3f50..bc55dd39 100644 --- a/docs/auto_examples/plot_digits.ipynb +++ b/docs/auto_examples/plot_digits.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Visualizing the digits dataset\n\nThis example loads in some data from the scikit-learn digits dataset and plots\nit.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nfrom sklearn import datasets\nimport hypertools as hyp\n\n# load example data\ndigits = datasets.load_digits(n_class=6)\ndata = digits.data\nhue = digits.target\n\n# plot\nhyp.plot(data, '.', hue=hue)" + ] + } + ], + "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# Visualizing the digits dataset\n\nThis example loads in some data from the scikit-learn digits dataset and plots\nit.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nfrom sklearn import datasets\nimport hypertools as hyp\n\n# load example data\ndigits = datasets.load_digits(n_class=6)\ndata = digits.data\nhue = digits.target\n\n# plot\nhyp.plot(data, '.', hue=hue)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_digits.rst b/docs/auto_examples/plot_digits.rst index a4c5bd10..f5995497 100644 --- a/docs/auto_examples/plot_digits.rst +++ b/docs/auto_examples/plot_digits.rst @@ -35,20 +35,8 @@ it. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( - - - - - - - -| .. code-block:: Python @@ -71,7 +59,7 @@ it. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.520 seconds) + **Total running time of the script:** (0 minutes 0.076 seconds) .. _sphx_glr_download_auto_examples_plot_digits.py: diff --git a/docs/auto_examples/plot_digits.zip b/docs/auto_examples/plot_digits.zip index 01008886..9edd33f6 100644 Binary files a/docs/auto_examples/plot_digits.zip and b/docs/auto_examples/plot_digits.zip differ diff --git a/docs/auto_examples/plot_geo.codeobj.json b/docs/auto_examples/plot_geo.codeobj.json index 11eeaea3..e61036da 100644 --- a/docs/auto_examples/plot_geo.codeobj.json +++ b/docs/auto_examples/plot_geo.codeobj.json @@ -1,34 +1,154 @@ { - "geo": [ + "ax": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry" + "module": "mpl_toolkits.mplot3d.axes3d", + "module_short": "mpl_toolkits.mplot3d", + "name": "Axes3D" }, { "is_class": false, "is_explicit": false, - "module": "hypertools", - "module_short": "hypertools", - "name": "DataGeometry" + "module": "mpl_toolkits.mplot3d", + "module_short": "mpl_toolkits.mplot3d", + "name": "Axes3D" + }, + { + "is_class": false, + "is_explicit": false, + "module": "mpl_toolkits", + "module_short": "mpl_toolkits", + "name": "Axes3D" } ], - "geo.plot": [ + "data": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "fig": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" }, { "is_class": false, "is_explicit": false, - "module": "hypertools", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure" + } + ], + "fig.axes": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "FigureBase.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "FigureBase.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.artist", + "module_short": "matplotlib.artist", + "name": "Artist.axes" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Artist.axes" + } + ], + "fig.savefig": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure.savefig" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure.savefig" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "FigureBase.savefig" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "FigureBase.savefig" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.artist", + "module_short": "matplotlib.artist", + "name": "Artist.savefig" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Artist.savefig" + } + ], + "fig2": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure" } ], "hyp.load": [ @@ -47,20 +167,88 @@ "name": "load" } ], - "t": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry" + "name": "plot" + } + ], + "models": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "os.path.join": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "os.path", + "module_short": "os.path", + "name": "join" + } + ], + "out": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "png_path": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "str" + } + ], + "tempfile.mkdtemp": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "tempfile", + "module_short": "tempfile", + "name": "mkdtemp" + } + ], + "xform_data": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" } ] } \ No newline at end of file diff --git a/docs/auto_examples/plot_geo.ipynb b/docs/auto_examples/plot_geo.ipynb index 76f55b2b..cabfec1d 100644 --- a/docs/auto_examples/plot_geo.ipynb +++ b/docs/auto_examples/plot_geo.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Working with plot outputs (figures & fitted models)\n\n`hyp.plot` returns a plain matplotlib (or plotly) Figure -- there is no\nspecial container object to learn. Anything you can do with a Figure\n(``fig.savefig(...)``, grabbing ``fig.axes[0]`` to tweak the plot,\nembedding it in a larger layout, etc.) just works.\n\nIf you also want access to the analyzed data and the fitted\nreduce/align/cluster models, pass ``return_model=True``. Instead of the\nbare figure, `hyp.plot` then returns a dict bundle:\n``{'fig': ..., 'xform_data': ..., 'animation': ..., 'models': ...}``, where\n``xform_data`` is the normalized/reduced/aligned data that was actually\nplotted, ``animation`` is the ``matplotlib.animation.Animation`` handle when\n``animate=True`` (``None`` otherwise, and for plotly figures), and ``models``\nrecords the reduce/align/cluster specs used to produce it.\n\nNote that `hyp.load` returns raw data directly (e.g. a list of arrays) --\nthere is nothing further to unpack.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Lab\n# License: MIT\n\n# import\nimport os\nimport tempfile\nimport hypertools as hyp\n\n# load some data -- a list of arrays, ready to plot as-is\ndata = hyp.load('spiral')\n\n# plot: the return value is just a matplotlib Figure\nfig = hyp.plot(data, ndims=3)\n\n# treat it like any other Figure\npng_path = os.path.join(tempfile.mkdtemp(), 'spiral.png')\nfig.savefig(png_path)\nax = fig.axes[0]\nprint(f\"axes type: {type(ax).__name__}\")\n\n# ask for the fitted models and the analyzed data alongside the figure\nout = hyp.plot(data, ndims=3, reduce='PCA', return_model=True)\n\nfig2 = out['fig']\nxform_data = out['xform_data']\nmodels = out['models']\n\nprint(f\"number of arrays returned: {len(xform_data)}\")\nprint(f\"reduced shape (first array): {xform_data[0].shape}\")\nprint(f\"reduce model spec: {models['reduce']}\")" + ] + } + ], + "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# A DataGeometry object or \"geo\"\n\nWhen the plot function is called, it returns a DataGeometry object, or geo. A\ngeo contains all the pieces needed to regenerate the plot. You can use the geo\nplot method to evaluate the same plot with new arguments, like changing the color\nof the points, or trying a different normalization method. To save the plot,\nsimply call geo.save(fname), where fname is a file name/path. Then, this file\ncan be reloaded using hyp.load to be plotted again at another time. Finally,\nthe transform method can be used to transform new data using the same transformations\nthat were applied to the geo.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load some data\ngeo = hyp.load('mushrooms')\n\n# plot\nt = geo.plot()\n\n# replot with new parameters\ngeo.plot(normalize='within', color='green')\n\n# save the object\n# geo.save('test')\n\n# load it back in\n# geo = hyp.load('test.geo')\n\n# transform some new data\n# transformed_data = geo.transform(data)\n\n# transform some 'new' data and plot it\n# hyp.plot(transformed_data, '.')\n\n# get a copy of the data\n# geo.get_data()\n\n# get the formatted data\n# geo.get_formatted_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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_geo.py b/docs/auto_examples/plot_geo.py index 92ab0e06..45791a3a 100644 --- a/docs/auto_examples/plot_geo.py +++ b/docs/auto_examples/plot_geo.py @@ -1,48 +1,54 @@ # -*- coding: utf-8 -*- """ ============================= -A DataGeometry object or "geo" +Working with plot outputs (figures & fitted models) ============================= -When the plot function is called, it returns a DataGeometry object, or geo. A -geo contains all the pieces needed to regenerate the plot. You can use the geo -plot method to evaluate the same plot with new arguments, like changing the color -of the points, or trying a different normalization method. To save the plot, -simply call geo.save(fname), where fname is a file name/path. Then, this file -can be reloaded using hyp.load to be plotted again at another time. Finally, -the transform method can be used to transform new data using the same transformations -that were applied to the geo. +`hyp.plot` returns a plain matplotlib (or plotly) Figure -- there is no +special container object to learn. Anything you can do with a Figure +(``fig.savefig(...)``, grabbing ``fig.axes[0]`` to tweak the plot, +embedding it in a larger layout, etc.) just works. + +If you also want access to the analyzed data and the fitted +reduce/align/cluster models, pass ``return_model=True``. Instead of the +bare figure, `hyp.plot` then returns a dict bundle: +``{'fig': ..., 'xform_data': ..., 'animation': ..., 'models': ...}``, where +``xform_data`` is the normalized/reduced/aligned data that was actually +plotted, ``animation`` is the ``matplotlib.animation.Animation`` handle when +``animate=True`` (``None`` otherwise, and for plotly figures), and ``models`` +records the reduce/align/cluster specs used to produce it. + +Note that `hyp.load` returns raw data directly (e.g. a list of arrays) -- +there is nothing further to unpack. """ -# Code source: Andrew Heusser +# Code source: Contextual Dynamics Lab # License: MIT # import +import os +import tempfile import hypertools as hyp -# load some data -geo = hyp.load('mushrooms') +# load some data -- a list of arrays, ready to plot as-is +data = hyp.load('spiral') -# plot -t = geo.plot() +# plot: the return value is just a matplotlib Figure +fig = hyp.plot(data, ndims=3) -# replot with new parameters -geo.plot(normalize='within', color='green') +# treat it like any other Figure +png_path = os.path.join(tempfile.mkdtemp(), 'spiral.png') +fig.savefig(png_path) +ax = fig.axes[0] +print(f"axes type: {type(ax).__name__}") -# save the object -# geo.save('test') +# ask for the fitted models and the analyzed data alongside the figure +out = hyp.plot(data, ndims=3, reduce='PCA', return_model=True) -# load it back in -# geo = hyp.load('test.geo') +fig2 = out['fig'] +xform_data = out['xform_data'] +models = out['models'] -# transform some new data -# transformed_data = geo.transform(data) - -# transform some 'new' data and plot it -# hyp.plot(transformed_data, '.') - -# get a copy of the data -# geo.get_data() - -# get the formatted data -# geo.get_formatted_data() +print(f"number of arrays returned: {len(xform_data)}") +print(f"reduced shape (first array): {xform_data[0].shape}") +print(f"reduce model spec: {models['reduce']}") diff --git a/docs/auto_examples/plot_geo.py.md5 b/docs/auto_examples/plot_geo.py.md5 index 8adda69e..f84edd32 100644 --- a/docs/auto_examples/plot_geo.py.md5 +++ b/docs/auto_examples/plot_geo.py.md5 @@ -1 +1 @@ -39d831fdcda4e02006e1821975df97e8 \ No newline at end of file +f9c5734590d7de21ae33680629099cb0 \ No newline at end of file diff --git a/docs/auto_examples/plot_geo.rst b/docs/auto_examples/plot_geo.rst index 15919a53..777a2116 100644 --- a/docs/auto_examples/plot_geo.rst +++ b/docs/auto_examples/plot_geo.rst @@ -19,19 +19,27 @@ ============================= -A DataGeometry object or "geo" +Working with plot outputs (figures & fitted models) ============================= -When the plot function is called, it returns a DataGeometry object, or geo. A -geo contains all the pieces needed to regenerate the plot. You can use the geo -plot method to evaluate the same plot with new arguments, like changing the color -of the points, or trying a different normalization method. To save the plot, -simply call geo.save(fname), where fname is a file name/path. Then, this file -can be reloaded using hyp.load to be plotted again at another time. Finally, -the transform method can be used to transform new data using the same transformations -that were applied to the geo. +`hyp.plot` returns a plain matplotlib (or plotly) Figure -- there is no +special container object to learn. Anything you can do with a Figure +(``fig.savefig(...)``, grabbing ``fig.axes[0]`` to tweak the plot, +embedding it in a larger layout, etc.) just works. -.. GENERATED FROM PYTHON SOURCE LINES 16-49 +If you also want access to the analyzed data and the fitted +reduce/align/cluster models, pass ``return_model=True``. Instead of the +bare figure, `hyp.plot` then returns a dict bundle: +``{'fig': ..., 'xform_data': ..., 'animation': ..., 'models': ...}``, where +``xform_data`` is the normalized/reduced/aligned data that was actually +plotted, ``animation`` is the ``matplotlib.animation.Animation`` handle when +``animate=True`` (``None`` otherwise, and for plotly figures), and ``models`` +records the reduce/align/cluster specs used to produce it. + +Note that `hyp.load` returns raw data directly (e.g. a list of arrays) -- +there is nothing further to unpack. + +.. GENERATED FROM PYTHON SOURCE LINES 24-55 @@ -57,14 +65,11 @@ that were applied to the geo. .. code-block:: none - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( - /Users/jmanning/hypertools/hypertools/plot/plot.py:404: UserWarning: Using group, color keyword will be ignored. - warnings.warn("Using group, color keyword will be ignored.") - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( + axes type: Axes3D + number of arrays returned: 2 + reduced shape (first array): (1000, 3) + reduce model spec: {'model': 'PCA', 'params': {'n_components': 3}} - @@ -75,43 +80,41 @@ that were applied to the geo. .. code-block:: Python - # Code source: Andrew Heusser + # Code source: Contextual Dynamics Lab # License: MIT # import + import os + import tempfile import hypertools as hyp - # load some data - geo = hyp.load('mushrooms') - - # plot - t = geo.plot() - - # replot with new parameters - geo.plot(normalize='within', color='green') - - # save the object - # geo.save('test') + # load some data -- a list of arrays, ready to plot as-is + data = hyp.load('spiral') - # load it back in - # geo = hyp.load('test.geo') + # plot: the return value is just a matplotlib Figure + fig = hyp.plot(data, ndims=3) - # transform some new data - # transformed_data = geo.transform(data) + # treat it like any other Figure + png_path = os.path.join(tempfile.mkdtemp(), 'spiral.png') + fig.savefig(png_path) + ax = fig.axes[0] + print(f"axes type: {type(ax).__name__}") - # transform some 'new' data and plot it - # hyp.plot(transformed_data, '.') + # ask for the fitted models and the analyzed data alongside the figure + out = hyp.plot(data, ndims=3, reduce='PCA', return_model=True) - # get a copy of the data - # geo.get_data() + fig2 = out['fig'] + xform_data = out['xform_data'] + models = out['models'] - # get the formatted data - # geo.get_formatted_data() + print(f"number of arrays returned: {len(xform_data)}") + print(f"reduced shape (first array): {xform_data[0].shape}") + print(f"reduce model spec: {models['reduce']}") .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.166 seconds) + **Total running time of the script:** (0 minutes 0.042 seconds) .. _sphx_glr_download_auto_examples_plot_geo.py: diff --git a/docs/auto_examples/plot_geo.zip b/docs/auto_examples/plot_geo.zip index 577576eb..8a729ce4 100644 Binary files a/docs/auto_examples/plot_geo.zip and b/docs/auto_examples/plot_geo.zip differ diff --git a/docs/auto_examples/plot_hue.codeobj.json b/docs/auto_examples/plot_hue.codeobj.json index 61ff0449..007403c8 100644 --- a/docs/auto_examples/plot_hue.codeobj.json +++ b/docs/auto_examples/plot_hue.codeobj.json @@ -8,73 +8,41 @@ "name": "list" } ], - "geo": [ - { - "is_class": false, - "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry" - }, + "hue": [ { "is_class": false, "is_explicit": false, - "module": "hypertools", - "module_short": "hypertools", - "name": "DataGeometry" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "geo.get_data": [ - { - "is_class": false, - "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.get_data" - }, + "hue.append": [ { "is_class": false, "is_explicit": false, - "module": "hypertools", - "module_short": "hypertools", - "name": "DataGeometry.get_data" + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" - } - ], - "hue": [ - { - "is_class": false, - "is_explicit": false, - "module": "builtins", - "module_short": "builtins", - "name": "list" - } - ], - "hue.append": [ - { - "is_class": false, - "is_explicit": false, - "module": "builtins", - "module_short": "builtins", - "name": "builtin_function_or_method" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -87,7 +55,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ], "i": [ diff --git a/docs/auto_examples/plot_hue.ipynb b/docs/auto_examples/plot_hue.ipynb index 118e4e8c..1d533105 100644 --- a/docs/auto_examples/plot_hue.ipynb +++ b/docs/auto_examples/plot_hue.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Grouping data by category\n\nWhen plotting, its useful to have a way to color points by some category or\nvariable. Hypertools does this using the `hue` kwarg, which takes a list\nof string category labels or numerical values. If text labels are passed, the\ndata is restructured according to those labels and plotted in different colors\naccording to your color palette. If numerical values are passed, the values\nare binned (default resolution: 100) and plotted according to your color\npalette.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ndata = hyp.load('weights_sample')\n\n# simulate random groups\nhue=[]\nfor idx,i in enumerate(data):\n tmp=[]\n for iidx,ii in enumerate(i):\n tmp.append(int(np.random.randint(1000, size=1)))\n hue.append(tmp)\n\n# plot\nhyp.plot(data, fmt='.', hue=hue)" + ] + } + ], + "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# Grouping data by category\n\nWhen plotting, its useful to have a way to color points by some category or\nvariable. Hypertools does this using the `hue` kwarg, which takes a list\nof string category labels or numerical values. If text labels are passed, the\ndata is restructured according to those labels and plotted in different colors\naccording to your color palette. If numerical values are passed, the values\nare binned (default resolution: 100) and plotted according to your color\npalette.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ngeo = hyp.load('weights_sample')\ndata = geo.get_data()\n\n# simulate random groups\nhue=[]\nfor idx,i in enumerate(data):\n tmp=[]\n for iidx,ii in enumerate(i):\n tmp.append(int(np.random.randint(1000, size=1)))\n hue.append(tmp)\n\n# plot\ngeo.plot(fmt='.', hue=hue)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_hue.py b/docs/auto_examples/plot_hue.py index f715fe7e..26518565 100644 --- a/docs/auto_examples/plot_hue.py +++ b/docs/auto_examples/plot_hue.py @@ -21,8 +21,7 @@ import numpy as np # load example data -geo = hyp.load('weights_sample') -data = geo.get_data() +data = hyp.load('weights_sample') # simulate random groups hue=[] @@ -33,4 +32,4 @@ hue.append(tmp) # plot -geo.plot(fmt='.', hue=hue) +hyp.plot(data, fmt='.', hue=hue) diff --git a/docs/auto_examples/plot_hue.py.md5 b/docs/auto_examples/plot_hue.py.md5 index f59ba28a..9b71c43b 100644 --- a/docs/auto_examples/plot_hue.py.md5 +++ b/docs/auto_examples/plot_hue.py.md5 @@ -1 +1 @@ -4913519f86c2e0e6342e96ba0c564181 \ No newline at end of file +834a34641039f7efc9cd64d92719b418 \ No newline at end of file diff --git a/docs/auto_examples/plot_hue.rst b/docs/auto_examples/plot_hue.rst index 203611b2..62c7d25c 100644 --- a/docs/auto_examples/plot_hue.rst +++ b/docs/auto_examples/plot_hue.rst @@ -30,7 +30,7 @@ according to your color palette. If numerical values are passed, the values are binned (default resolution: 100) and plotted according to your color palette. -.. GENERATED FROM PYTHON SOURCE LINES 15-37 +.. GENERATED FROM PYTHON SOURCE LINES 15-36 @@ -44,12 +44,9 @@ palette. .. code-block:: none - /Users/jmanning/hypertools/examples/plot_hue.py:32: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.) + /Users/jmanning/hypertools/examples/plot_hue.py:31: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.) tmp.append(int(np.random.randint(1000, size=1))) - /Users/jmanning/hypertools/hypertools/plot/plot.py:577: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( - @@ -68,8 +65,7 @@ palette. import numpy as np # load example data - geo = hyp.load('weights_sample') - data = geo.get_data() + data = hyp.load('weights_sample') # simulate random groups hue=[] @@ -80,12 +76,12 @@ palette. hue.append(tmp) # plot - geo.plot(fmt='.', hue=hue) + hyp.plot(data, fmt='.', hue=hue) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.069 seconds) + **Total running time of the script:** (0 minutes 0.081 seconds) .. _sphx_glr_download_auto_examples_plot_hue.py: diff --git a/docs/auto_examples/plot_hue.zip b/docs/auto_examples/plot_hue.zip index 110a71ce..b648784b 100644 Binary files a/docs/auto_examples/plot_hue.zip and b/docs/auto_examples/plot_hue.zip differ diff --git a/docs/auto_examples/plot_impute.codeobj.json b/docs/auto_examples/plot_impute.codeobj.json new file mode 100644 index 00000000..be84c618 --- /dev/null +++ b/docs/auto_examples/plot_impute.codeobj.json @@ -0,0 +1,418 @@ +{ + "axes": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "cols": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "data": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "data.copy": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" + } + ], + "fig": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure" + } + ], + "flat_inds": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "hyp.impute": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "impute" + } + ], + "hyp.load": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "load" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "kalman_imputed": [ + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" + } + ], + "missing": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "missing.shape": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "tuple" + } + ], + "n_cols": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "n_missing": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "n_rows": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "np.nan": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "nan" + } + ], + "np.random.choice": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "module.choice" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "choice" + } + ], + "np.random.seed": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_2_1", + "module_short": "_cython_3_2_1", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "seed" + } + ], + "np.unravel_index": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "unravel_index" + } + ], + "plt.show": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "show" + } + ], + "plt.subplots": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "subplots" + } + ], + "plt.tight_layout": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "tight_layout" + } + ], + "ppca_imputed": [ + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" + } + ], + "ppca_imputed.dropna": [ + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.generic", + "module_short": "pandas.core.generic", + "name": "NDFrame.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "NDFrame.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "NDFrame.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.arraylike", + "module_short": "pandas.core.arraylike", + "name": "OpsMixin.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "OpsMixin.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "OpsMixin.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.base", + "module_short": "pandas.core.base", + "name": "PandasObject.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "PandasObject.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "PandasObject.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.indexing", + "module_short": "pandas.core.indexing", + "name": "IndexingMixin.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "IndexingMixin.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "IndexingMixin.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core.accessor", + "module_short": "pandas.core.accessor", + "name": "DirNamesMixin.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "DirNamesMixin.dropna" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DirNamesMixin.dropna" + } + ], + "ppca_plottable": [ + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" + } + ], + "rows": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/plot_impute.ipynb b/docs/auto_examples/plot_impute.ipynb new file mode 100644 index 00000000..34256de7 --- /dev/null +++ b/docs/auto_examples/plot_impute.ipynb @@ -0,0 +1,54 @@ +{ + "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# Imputing missing data: PPCA vs Kalman smoothing\n\nHypertools fills missing (NaN) values via `hypertools.impute` before\nreducing/plotting. This compares two imputers on the `weights_avg` dataset\nafter randomly knocking out 10% of its entries -- plus three CONSECUTIVE\nrows where every feature is missing. That fully-missing-row case is the\nmotivating example for GH #169: PPCA reconstructs a row from its own\nobserved features, so a row with NO observed features at all cannot be\nrecovered, so PPCA warns and leaves those rows NaN (they are dropped below\npurely so the PPCA panel has something plottable). The Kalman imputer\ninstead smooths across time, so it can fill a fully-missing row from the\nneighboring (observed) timepoints, at the cost of assuming the data are a\nreasonably smooth timeseries -- its panel keeps every row.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\n# import\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport hypertools as hyp\n\n# load example data and knock out some values\nnp.random.seed(42)\ndata = hyp.load('weights_avg')[0]\nmissing = data.copy()\nn_rows, n_cols = missing.shape\n\n# randomly remove 10% of the entries\nn_missing = int(0.1 * n_rows * n_cols)\nflat_inds = np.random.choice(n_rows * n_cols, size=n_missing, replace=False)\nrows, cols = np.unravel_index(flat_inds, (n_rows, n_cols))\nmissing[rows, cols] = np.nan\n\n# knock out 3 consecutive fully-missing rows (the GH #169 case)\nmissing[40:43, :] = np.nan\n\n# impute with PPCA (cannot fill the fully-NaN rows) and Kalman (can)\nppca_imputed = hyp.impute(missing, model='PPCA')\nkalman_imputed = hyp.impute(missing, model='Kalman')\n\n# PPCA cannot reconstruct rows with zero observed features, so those 3 rows\n# come back as NaN; drop them before plotting (there is nothing left to\n# reduce/plot for that timepoint). Kalman fills every row, so nothing to drop.\nppca_plottable = ppca_imputed.dropna(axis=0, how='all')\n\n# plot side by side\nfig, axes = plt.subplots(1, 2, subplot_kw={'projection': '3d'})\nhyp.plot(ppca_plottable, ax=axes[0],\n title=f'PPCA ({n_rows - len(ppca_plottable)} unfillable rows dropped)')\nhyp.plot(kalman_imputed, ax=axes[1], title='Kalman (all rows filled)')\nplt.tight_layout()\nplt.show()" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_impute.py b/docs/auto_examples/plot_impute.py new file mode 100644 index 00000000..52b59f18 --- /dev/null +++ b/docs/auto_examples/plot_impute.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +""" +============================= +Imputing missing data: PPCA vs Kalman smoothing +============================= + +Hypertools fills missing (NaN) values via `hypertools.impute` before +reducing/plotting. This compares two imputers on the `weights_avg` dataset +after randomly knocking out 10% of its entries -- plus three CONSECUTIVE +rows where every feature is missing. That fully-missing-row case is the +motivating example for GH #169: PPCA reconstructs a row from its own +observed features, so a row with NO observed features at all cannot be +recovered, so PPCA warns and leaves those rows NaN (they are dropped below +purely so the PPCA panel has something plottable). The Kalman imputer +instead smooths across time, so it can fill a fully-missing row from the +neighboring (observed) timepoints, at the cost of assuming the data are a +reasonably smooth timeseries -- its panel keeps every row. +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +# import +import numpy as np +import matplotlib.pyplot as plt +import hypertools as hyp + +# load example data and knock out some values +np.random.seed(42) +data = hyp.load('weights_avg')[0] +missing = data.copy() +n_rows, n_cols = missing.shape + +# randomly remove 10% of the entries +n_missing = int(0.1 * n_rows * n_cols) +flat_inds = np.random.choice(n_rows * n_cols, size=n_missing, replace=False) +rows, cols = np.unravel_index(flat_inds, (n_rows, n_cols)) +missing[rows, cols] = np.nan + +# knock out 3 consecutive fully-missing rows (the GH #169 case) +missing[40:43, :] = np.nan + +# impute with PPCA (cannot fill the fully-NaN rows) and Kalman (can) +ppca_imputed = hyp.impute(missing, model='PPCA') +kalman_imputed = hyp.impute(missing, model='Kalman') + +# PPCA cannot reconstruct rows with zero observed features, so those 3 rows +# come back as NaN; drop them before plotting (there is nothing left to +# reduce/plot for that timepoint). Kalman fills every row, so nothing to drop. +ppca_plottable = ppca_imputed.dropna(axis=0, how='all') + +# plot side by side +fig, axes = plt.subplots(1, 2, subplot_kw={'projection': '3d'}) +hyp.plot(ppca_plottable, ax=axes[0], + title=f'PPCA ({n_rows - len(ppca_plottable)} unfillable rows dropped)') +hyp.plot(kalman_imputed, ax=axes[1], title='Kalman (all rows filled)') +plt.tight_layout() +plt.show() diff --git a/docs/auto_examples/plot_impute.py.md5 b/docs/auto_examples/plot_impute.py.md5 new file mode 100644 index 00000000..5d5e3188 --- /dev/null +++ b/docs/auto_examples/plot_impute.py.md5 @@ -0,0 +1 @@ +d6ee8a2426245debdd8a16066657881c \ No newline at end of file diff --git a/docs/auto_examples/plot_impute.rst b/docs/auto_examples/plot_impute.rst new file mode 100644 index 00000000..c0c13155 --- /dev/null +++ b/docs/auto_examples/plot_impute.rst @@ -0,0 +1,133 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/plot_impute.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_plot_impute.py: + + +============================= +Imputing missing data: PPCA vs Kalman smoothing +============================= + +Hypertools fills missing (NaN) values via `hypertools.impute` before +reducing/plotting. This compares two imputers on the `weights_avg` dataset +after randomly knocking out 10% of its entries -- plus three CONSECUTIVE +rows where every feature is missing. That fully-missing-row case is the +motivating example for GH #169: PPCA reconstructs a row from its own +observed features, so a row with NO observed features at all cannot be +recovered, so PPCA warns and leaves those rows NaN (they are dropped below +purely so the PPCA panel has something plottable). The Kalman imputer +instead smooths across time, so it can fill a fully-missing row from the +neighboring (observed) timepoints, at the cost of assuming the data are a +reasonably smooth timeseries -- its panel keeps every row. + +.. GENERATED FROM PYTHON SOURCE LINES 19-59 + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_impute_001.png + :alt: PPCA (3 unfillable rows dropped), Kalman (all rows filled) + :srcset: /auto_examples/images/sphx_glr_plot_impute_001.png + :class: sphx-glr-single-img + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + /Users/jmanning/hypertools/hypertools/impute/ppca.py:36: UserWarning: PPCA cannot fill 3 row(s) with no observed features at all; those rows will remain NaN. Use model='Kalman' (hypertools.impute.kalman.Kalman) to fill fully-missing rows too (see GH #169). + warnings.warn( + + + + + + +| + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + # import + import numpy as np + import matplotlib.pyplot as plt + import hypertools as hyp + + # load example data and knock out some values + np.random.seed(42) + data = hyp.load('weights_avg')[0] + missing = data.copy() + n_rows, n_cols = missing.shape + + # randomly remove 10% of the entries + n_missing = int(0.1 * n_rows * n_cols) + flat_inds = np.random.choice(n_rows * n_cols, size=n_missing, replace=False) + rows, cols = np.unravel_index(flat_inds, (n_rows, n_cols)) + missing[rows, cols] = np.nan + + # knock out 3 consecutive fully-missing rows (the GH #169 case) + missing[40:43, :] = np.nan + + # impute with PPCA (cannot fill the fully-NaN rows) and Kalman (can) + ppca_imputed = hyp.impute(missing, model='PPCA') + kalman_imputed = hyp.impute(missing, model='Kalman') + + # PPCA cannot reconstruct rows with zero observed features, so those 3 rows + # come back as NaN; drop them before plotting (there is nothing left to + # reduce/plot for that timepoint). Kalman fills every row, so nothing to drop. + ppca_plottable = ppca_imputed.dropna(axis=0, how='all') + + # plot side by side + fig, axes = plt.subplots(1, 2, subplot_kw={'projection': '3d'}) + hyp.plot(ppca_plottable, ax=axes[0], + title=f'PPCA ({n_rows - len(ppca_plottable)} unfillable rows dropped)') + hyp.plot(kalman_imputed, ax=axes[1], title='Kalman (all rows filled)') + plt.tight_layout() + plt.show() + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 0.839 seconds) + + +.. _sphx_glr_download_auto_examples_plot_impute.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: plot_impute.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: plot_impute.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: plot_impute.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/plot_impute.zip b/docs/auto_examples/plot_impute.zip new file mode 100644 index 00000000..1e24cdb6 Binary files /dev/null and b/docs/auto_examples/plot_impute.zip differ diff --git a/docs/auto_examples/plot_interactive_backend.ipynb b/docs/auto_examples/plot_interactive_backend.ipynb index 60386abe..d20230b7 100644 --- a/docs/auto_examples/plot_interactive_backend.ipynb +++ b/docs/auto_examples/plot_interactive_backend.ipynb @@ -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# Interactive plotting with the plotly backend\n\nHyperTools 1.0 can render any plot with plotly instead of matplotlib by\npassing `backend='plotly'` -- handy for rotating and zooming 3D plots\ninteractively. With the default `backend='auto'`, hypertools automatically\nuses plotly on Google Colab and Kaggle notebooks (where plotly is\npreinstalled and interactivity works best) and matplotlib everywhere else,\nso existing workflows are unchanged. Both backends produce the same styling:\ncolors, line/marker sizes, format strings, and the signature cube frame.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\ndata = np.cumsum(np.random.default_rng(42).standard_normal((200, 10)),\n axis=0)\n\n# classic matplotlib render (the default outside Colab/Kaggle)\nhyp.plot(data, backend='matplotlib')\n\n# identical call, interactive plotly render (in the docs gallery this is\n# captured as an image; in a notebook it is fully interactive)\nhyp.plot(data, backend='plotly')" + ] + } + ], + "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# Interactive plotting with the plotly backend\n\nHyperTools 2.0 can render any plot with plotly instead of matplotlib by\npassing `backend='plotly'` -- handy for rotating and zooming 3D plots\ninteractively. With the default `backend='auto'`, hypertools automatically\nuses plotly on Google Colab and Kaggle notebooks (where plotly is\npreinstalled and interactivity works best) and matplotlib everywhere else,\nso existing workflows are unchanged. Both backends produce the same styling:\ncolors, line/marker sizes, format strings, and the signature cube frame.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\ndata = np.cumsum(np.random.default_rng(42).standard_normal((200, 10)),\n axis=0)\n\n# classic matplotlib render (the default outside Colab/Kaggle)\nhyp.plot(data, backend='matplotlib')\n\n# identical call, interactive plotly render (in the docs gallery this is\n# captured as an image; in a notebook it is fully interactive)\nhyp.plot(data, backend='plotly')" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_interactive_backend.py b/docs/auto_examples/plot_interactive_backend.py index f665b8b5..63e500f0 100644 --- a/docs/auto_examples/plot_interactive_backend.py +++ b/docs/auto_examples/plot_interactive_backend.py @@ -4,7 +4,7 @@ Interactive plotting with the plotly backend ============================= -HyperTools 2.0 can render any plot with plotly instead of matplotlib by +HyperTools 1.0 can render any plot with plotly instead of matplotlib by passing `backend='plotly'` -- handy for rotating and zooming 3D plots interactively. With the default `backend='auto'`, hypertools automatically uses plotly on Google Colab and Kaggle notebooks (where plotly is diff --git a/docs/auto_examples/plot_interactive_backend.py.md5 b/docs/auto_examples/plot_interactive_backend.py.md5 index 7aab2125..63e497e3 100644 --- a/docs/auto_examples/plot_interactive_backend.py.md5 +++ b/docs/auto_examples/plot_interactive_backend.py.md5 @@ -1 +1 @@ -26da1dc23f398c9cf41f8fb52dad7f22 \ No newline at end of file +4b3f4e1e4ba99bb9e028c68d99d23b4f \ No newline at end of file diff --git a/docs/auto_examples/plot_interactive_backend.rst b/docs/auto_examples/plot_interactive_backend.rst index 38f7bf9b..62076416 100644 --- a/docs/auto_examples/plot_interactive_backend.rst +++ b/docs/auto_examples/plot_interactive_backend.rst @@ -22,7 +22,7 @@ Interactive plotting with the plotly backend ============================= -HyperTools 2.0 can render any plot with plotly instead of matplotlib by +HyperTools 1.0 can render any plot with plotly instead of matplotlib by passing `backend='plotly'` -- handy for rotating and zooming 3D plots interactively. With the default `backend='auto'`, hypertools automatically uses plotly on Google Colab and Kaggle notebooks (where plotly is @@ -44,7 +44,14 @@ colors, line/marker sizes, format strings, and the signature cube frame. +.. raw:: html +
+
+
+
+
+
.. code-block:: Python @@ -68,7 +75,7 @@ colors, line/marker sizes, format strings, and the signature cube frame. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 2.980 seconds) + **Total running time of the script:** (0 minutes 3.341 seconds) .. _sphx_glr_download_auto_examples_plot_interactive_backend.py: diff --git a/docs/auto_examples/plot_interactive_backend.zip b/docs/auto_examples/plot_interactive_backend.zip index 9a5a49c7..766c642e 100644 Binary files a/docs/auto_examples/plot_interactive_backend.zip and b/docs/auto_examples/plot_interactive_backend.zip differ diff --git a/docs/auto_examples/plot_labels.codeobj.json b/docs/auto_examples/plot_labels.codeobj.json index 6f73c6d3..512780d3 100644 --- a/docs/auto_examples/plot_labels.codeobj.json +++ b/docs/auto_examples/plot_labels.codeobj.json @@ -8,55 +8,23 @@ "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" - } - ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -69,7 +37,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ], "i": [ diff --git a/docs/auto_examples/plot_labels.ipynb b/docs/auto_examples/plot_labels.ipynb index 77199a85..6bbf2fbb 100644 --- a/docs/auto_examples/plot_labels.ipynb +++ b/docs/auto_examples/plot_labels.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Labeling your datapoints\n\nThis is an example of how to use the `label(s)` kwarg, which must be a list the\nlength of the number of datapoints (rows) you have in the matrix. Here, we\nare simply labeling the first datapoint for each matrix in the list.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ndata = hyp.load('weights_sample')\n\n# simulate labels\nlabels=[]\nfor idx,i in enumerate(data):\n tmp=[]\n for iidx,ii in enumerate(i):\n if iidx==0:\n tmp.append('Subject ' + str(idx))\n else:\n tmp.append(None)\n labels.append(tmp)\n\n# plot\nhyp.plot(data, fmt='.', labels=labels)" + ] + } + ], + "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# Labeling your datapoints\n\nThis is an example of how to use the `label(s)` kwarg, which must be a list the\nlength of the number of datapoints (rows) you have in the matrix. Here, we\nare simply labeling the first datapoint for each matrix in the list.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ngeo = hyp.load('weights_sample')\ndata = geo.get_data()\n\n# simulate labels\nlabels=[]\nfor idx,i in enumerate(data):\n tmp=[]\n for iidx,ii in enumerate(i):\n if iidx==0:\n tmp.append('Subject ' + str(idx))\n else:\n tmp.append(None)\n labels.append(tmp)\n\n# plot\ngeo.plot(fmt='.', labels=labels)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_labels.py b/docs/auto_examples/plot_labels.py index 0d31d951..4f0edfc7 100644 --- a/docs/auto_examples/plot_labels.py +++ b/docs/auto_examples/plot_labels.py @@ -17,8 +17,7 @@ import numpy as np # load example data -geo = hyp.load('weights_sample') -data = geo.get_data() +data = hyp.load('weights_sample') # simulate labels labels=[] @@ -32,4 +31,4 @@ labels.append(tmp) # plot -geo.plot(fmt='.', labels=labels) +hyp.plot(data, fmt='.', labels=labels) diff --git a/docs/auto_examples/plot_labels.py.md5 b/docs/auto_examples/plot_labels.py.md5 index 641f4d05..d3e8a8d8 100644 --- a/docs/auto_examples/plot_labels.py.md5 +++ b/docs/auto_examples/plot_labels.py.md5 @@ -1 +1 @@ -2d2c2ec87a7baa1363db66582ea09284 \ No newline at end of file +55c50435192a3bb939c812af5900269e \ No newline at end of file diff --git a/docs/auto_examples/plot_labels.rst b/docs/auto_examples/plot_labels.rst index 570cc1bb..1982d89b 100644 --- a/docs/auto_examples/plot_labels.rst +++ b/docs/auto_examples/plot_labels.rst @@ -26,7 +26,7 @@ This is an example of how to use the `label(s)` kwarg, which must be a list the length of the number of datapoints (rows) you have in the matrix. Here, we are simply labeling the first datapoint for each matrix in the list. -.. GENERATED FROM PYTHON SOURCE LINES 11-36 +.. GENERATED FROM PYTHON SOURCE LINES 11-35 @@ -36,19 +36,9 @@ are simply labeling the first datapoint for each matrix in the list. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - - - - - - -| - .. code-block:: Python @@ -60,8 +50,7 @@ are simply labeling the first datapoint for each matrix in the list. import numpy as np # load example data - geo = hyp.load('weights_sample') - data = geo.get_data() + data = hyp.load('weights_sample') # simulate labels labels=[] @@ -75,12 +64,12 @@ are simply labeling the first datapoint for each matrix in the list. labels.append(tmp) # plot - geo.plot(fmt='.', labels=labels) + hyp.plot(data, fmt='.', labels=labels) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.044 seconds) + **Total running time of the script:** (0 minutes 0.046 seconds) .. _sphx_glr_download_auto_examples_plot_labels.py: diff --git a/docs/auto_examples/plot_labels.zip b/docs/auto_examples/plot_labels.zip index fae487e6..d1db25ae 100644 Binary files a/docs/auto_examples/plot_labels.zip and b/docs/auto_examples/plot_labels.zip differ diff --git a/docs/auto_examples/plot_legend.codeobj.json b/docs/auto_examples/plot_legend.codeobj.json index 11d4a30b..fae7d364 100644 --- a/docs/auto_examples/plot_legend.codeobj.json +++ b/docs/auto_examples/plot_legend.codeobj.json @@ -1,37 +1,30 @@ { - "geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -44,7 +37,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/plot_legend.ipynb b/docs/auto_examples/plot_legend.ipynb index 2f276fa8..1a5034ad 100644 --- a/docs/auto_examples/plot_legend.ipynb +++ b/docs/auto_examples/plot_legend.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Generating a legend\n\nAn example of how to use the `legend` kwarg to generate a legend.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ndata = hyp.load('weights_sample')\n\n# plot\nhyp.plot(data, fmt='.', legend=['Group A', 'Group B', 'Group C'])" + ] + } + ], + "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# Generating a legend\n\nAn example of how to use the `legend` kwarg to generate a legend.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\n\n# load example data\ngeo = hyp.load('weights_sample')\n\n# plot\ngeo.plot(fmt='.', legend=['Group A', 'Group B', 'Group C'])" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_legend.py b/docs/auto_examples/plot_legend.py index 10d3fa1c..f1aa5cd5 100644 --- a/docs/auto_examples/plot_legend.py +++ b/docs/auto_examples/plot_legend.py @@ -14,7 +14,7 @@ import hypertools as hyp # load example data -geo = hyp.load('weights_sample') +data = hyp.load('weights_sample') # plot -geo.plot(fmt='.', legend=['Group A', 'Group B', 'Group C']) +hyp.plot(data, fmt='.', legend=['Group A', 'Group B', 'Group C']) diff --git a/docs/auto_examples/plot_legend.py.md5 b/docs/auto_examples/plot_legend.py.md5 index 8b6cfde3..4e0d1c85 100644 --- a/docs/auto_examples/plot_legend.py.md5 +++ b/docs/auto_examples/plot_legend.py.md5 @@ -1 +1 @@ -f80e548a7fe8d3bbc58a0e149525a258 \ No newline at end of file +69f733e83a399d1ba0d8e48807158b60 \ No newline at end of file diff --git a/docs/auto_examples/plot_legend.rst b/docs/auto_examples/plot_legend.rst index 20133830..5f7690ef 100644 --- a/docs/auto_examples/plot_legend.rst +++ b/docs/auto_examples/plot_legend.rst @@ -34,19 +34,9 @@ An example of how to use the `legend` kwarg to generate a legend. :class: sphx-glr-single-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - - - - - - -| - .. code-block:: Python @@ -57,15 +47,15 @@ An example of how to use the `legend` kwarg to generate a legend. import hypertools as hyp # load example data - geo = hyp.load('weights_sample') + data = hyp.load('weights_sample') # plot - geo.plot(fmt='.', legend=['Group A', 'Group B', 'Group C']) + hyp.plot(data, fmt='.', legend=['Group A', 'Group B', 'Group C']) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.032 seconds) + **Total running time of the script:** (0 minutes 0.125 seconds) .. _sphx_glr_download_auto_examples_plot_legend.py: diff --git a/docs/auto_examples/plot_legend.zip b/docs/auto_examples/plot_legend.zip index babde2c3..0c9799fb 100644 Binary files a/docs/auto_examples/plot_legend.zip and b/docs/auto_examples/plot_legend.zip differ diff --git a/docs/auto_examples/plot_missing_data.ipynb b/docs/auto_examples/plot_missing_data.ipynb index 11af89f8..fb133717 100644 --- a/docs/auto_examples/plot_missing_data.ipynb +++ b/docs/auto_examples/plot_missing_data.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Using the missing_inds function to label interpolated values\n\nIf you have data with missing values, Hypertools will try to interpolate them\nusing PPCA. To visualize how well its doing, you can use the missing_inds\nfunction and then highlight the values that were interpolated. Here, we\ngenerated some synthetic data, removed some values, and then plotted the\noriginal data, data with missing values and highlighted the missing datapoints\nwith stars.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nfrom scipy.linalg import toeplitz\nimport numpy as np\nfrom copy import copy\nimport hypertools as hyp\n\n# simulate data\nK = 10 - toeplitz(np.arange(10))\ndata1 = np.cumsum(np.random.multivariate_normal(np.zeros(10), K, 250), axis=0)\ndata2 = copy(data1)\n\n# randomly remove 5% of the data\nmissing = .01\ninds = [(i,j) for i in range(data1.shape[0]) for j in range(data1.shape[1])]\nmissing_data = [inds[i] for i in np.random.choice(int(len(inds)), int(len(inds)*missing))]\nfor i,j in missing_data:\n data2[i,j]=np.nan\n\n# reduce the data\ndata1_r,data2_r = hyp.reduce([data1, data2], ndims=3)\n\n# pull out missing inds\nmissing_inds = hyp.tools.missing_inds(data2)\nmissing_data = data2_r[missing_inds, :]\n\n# plot\nhyp.plot([data1_r, data2_r, missing_data], ['-', '--', '*'],\n legend=['Full', 'Missing', 'Missing Points'])" + ] + } + ], + "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# Using the missing_inds function to label interpolated values\n\nIf you have data with missing values, Hypertools will try to interpolate them\nusing PPCA. To visualize how well its doing, you can use the missing_inds\nfunction and then highlight the values that were interpolated. Here, we\ngenerated some synthetic data, removed some values, and then plotted the\noriginal data, data with missing values and highlighted the missing datapoints\nwith stars.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nfrom scipy.linalg import toeplitz\nimport numpy as np\nfrom copy import copy\nimport hypertools as hyp\n\n# simulate data\nK = 10 - toeplitz(np.arange(10))\ndata1 = np.cumsum(np.random.multivariate_normal(np.zeros(10), K, 250), axis=0)\ndata2 = copy(data1)\n\n# randomly remove 5% of the data\nmissing = .01\ninds = [(i,j) for i in range(data1.shape[0]) for j in range(data1.shape[1])]\nmissing_data = [inds[i] for i in np.random.choice(int(len(inds)), int(len(inds)*missing))]\nfor i,j in missing_data:\n data2[i,j]=np.nan\n\n# reduce the data\ndata1_r,data2_r = hyp.reduce([data1, data2], ndims=3)\n\n# pull out missing inds\nmissing_inds = hyp.tools.missing_inds(data2)\nmissing_data = data2_r[missing_inds, :]\n\n# plot\nhyp.plot([data1_r, data2_r, missing_data], ['-', '--', '*'],\n legend=['Full', 'Missing', 'Missing Points'])" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_missing_data.rst b/docs/auto_examples/plot_missing_data.rst index 003950ee..06b1275c 100644 --- a/docs/auto_examples/plot_missing_data.rst +++ b/docs/auto_examples/plot_missing_data.rst @@ -43,10 +43,9 @@ with stars. .. code-block:: none - /Users/jmanning/hypertools/hypertools/tools/format_data.py:140: UserWarning: Missing data: Inexact solution computed with PPCA (see https://github.com/allentran/pca-magic for details) + /Users/jmanning/hypertools/hypertools/tools/format_data.py:131: UserWarning: Missing data: Inexact solution computed with PPCA (see https://github.com/allentran/pca-magic for details) warnings.warn('Missing data: Inexact solution computed with PPCA (see https://github.com/allentran/pca-magic for details)') - @@ -92,7 +91,7 @@ with stars. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.054 seconds) + **Total running time of the script:** (0 minutes 0.057 seconds) .. _sphx_glr_download_auto_examples_plot_missing_data.py: diff --git a/docs/auto_examples/plot_missing_data.zip b/docs/auto_examples/plot_missing_data.zip index 3cc96ec8..37f67943 100644 Binary files a/docs/auto_examples/plot_missing_data.zip and b/docs/auto_examples/plot_missing_data.zip differ diff --git a/docs/auto_examples/plot_mixture_models.ipynb b/docs/auto_examples/plot_mixture_models.ipynb index d6284013..8ae6466a 100644 --- a/docs/auto_examples/plot_mixture_models.ipynb +++ b/docs/auto_examples/plot_mixture_models.ipynb @@ -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# Soft clustering with mixture models\n\nIn addition to hard clustering (KMeans, HDBSCAN, ...), hypertools 1.0\nsupports mixture models: GaussianMixture, BayesianGaussianMixture,\nLatentDirichletAllocation, and NMF. `hyp.cluster` returns an\n(n_samples, n_components) matrix of membership proportions instead of\ndiscrete labels, and `hyp.plot` colors each observation by blending the\ncomponent colors according to its mixture weights -- observations between\nclusters render with intermediate colors.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\n# three OVERLAPPING gaussian blobs (1.5 sd apart) -- points in the overlap\n# regions have genuinely mixed memberships, so their colors visibly blend\nrng = np.random.default_rng(42)\ndata = np.vstack([rng.standard_normal((100, 5)) + 1.5 * i for i in range(3)])\n\n# soft cluster assignments: rows sum to 1\nproportions = hyp.cluster(data, cluster='GaussianMixture', n_clusters=3)\nprint(proportions.shape, proportions[:2].round(3))\n\n# colors blend according to membership weights\nhyp.plot(data, 'o', cluster='GaussianMixture', n_clusters=3)\n\n# equivalently, pass any (n_samples, k) matrix as hue\nhyp.plot(data, 'o', hue=proportions)" + ] + } + ], + "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# Soft clustering with mixture models\n\nIn addition to hard clustering (KMeans, HDBSCAN, ...), hypertools 2.0\nsupports mixture models: GaussianMixture, BayesianGaussianMixture,\nLatentDirichletAllocation, and NMF. `hyp.cluster` returns an\n(n_samples, n_components) matrix of membership proportions instead of\ndiscrete labels, and `hyp.plot` colors each observation by blending the\ncomponent colors according to its mixture weights -- observations between\nclusters render with intermediate colors.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\n# three OVERLAPPING gaussian blobs (1.5 sd apart) -- points in the overlap\n# regions have genuinely mixed memberships, so their colors visibly blend\nrng = np.random.default_rng(42)\ndata = np.vstack([rng.standard_normal((100, 5)) + 1.5 * i for i in range(3)])\n\n# soft cluster assignments: rows sum to 1\nproportions = hyp.cluster(data, cluster='GaussianMixture', n_clusters=3)\nprint(proportions.shape, proportions[:2].round(3))\n\n# colors blend according to membership weights\nhyp.plot(data, 'o', cluster='GaussianMixture', n_clusters=3)\n\n# equivalently, pass any (n_samples, k) matrix as hue\nhyp.plot(data, 'o', hue=proportions)" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_mixture_models.py b/docs/auto_examples/plot_mixture_models.py index a01ebbc3..ebb7961a 100644 --- a/docs/auto_examples/plot_mixture_models.py +++ b/docs/auto_examples/plot_mixture_models.py @@ -4,7 +4,7 @@ Soft clustering with mixture models ============================= -In addition to hard clustering (KMeans, HDBSCAN, ...), hypertools 2.0 +In addition to hard clustering (KMeans, HDBSCAN, ...), hypertools 1.0 supports mixture models: GaussianMixture, BayesianGaussianMixture, LatentDirichletAllocation, and NMF. `hyp.cluster` returns an (n_samples, n_components) matrix of membership proportions instead of diff --git a/docs/auto_examples/plot_mixture_models.py.md5 b/docs/auto_examples/plot_mixture_models.py.md5 index 71cfa66c..a5b876c3 100644 --- a/docs/auto_examples/plot_mixture_models.py.md5 +++ b/docs/auto_examples/plot_mixture_models.py.md5 @@ -1 +1 @@ -46e1508161ad139bacd1b1d0cb6301f6 \ No newline at end of file +8066b87eacd7c91129f5ab566d22f955 \ No newline at end of file diff --git a/docs/auto_examples/plot_mixture_models.rst b/docs/auto_examples/plot_mixture_models.rst index a749b860..76cfd06c 100644 --- a/docs/auto_examples/plot_mixture_models.rst +++ b/docs/auto_examples/plot_mixture_models.rst @@ -22,7 +22,7 @@ Soft clustering with mixture models ============================= -In addition to hard clustering (KMeans, HDBSCAN, ...), hypertools 2.0 +In addition to hard clustering (KMeans, HDBSCAN, ...), hypertools 1.0 supports mixture models: GaussianMixture, BayesianGaussianMixture, LatentDirichletAllocation, and NMF. `hyp.cluster` returns an (n_samples, n_components) matrix of membership proportions instead of @@ -56,12 +56,8 @@ clusters render with intermediate colors. .. code-block:: none - (300, 3) [[0. 0.997 0.003] - [0. 0.997 0.003]] - /Users/jmanning/hypertools/hypertools/plot/plot.py:744: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( - /Users/jmanning/hypertools/hypertools/plot/plot.py:744: UserWarning: Could not convert all list arguments to numpy arrays. If list is longer than 256 items, it will automatically be pickled, which could cause Python 2/3 compatibility issues for the DataGeometry object. - warnings.warn( + (300, 3) [[0.997 0.003 0. ] + [0.997 0.003 0. ]] @@ -97,7 +93,7 @@ clusters render with intermediate colors. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.086 seconds) + **Total running time of the script:** (0 minutes 0.088 seconds) .. _sphx_glr_download_auto_examples_plot_mixture_models.py: diff --git a/docs/auto_examples/plot_mixture_models.zip b/docs/auto_examples/plot_mixture_models.zip index 658e883f..def5c290 100644 Binary files a/docs/auto_examples/plot_mixture_models.zip and b/docs/auto_examples/plot_mixture_models.zip differ diff --git a/docs/auto_examples/plot_multicolored_lines.ipynb b/docs/auto_examples/plot_multicolored_lines.ipynb index 87ed25fb..fd688a4c 100644 --- a/docs/auto_examples/plot_multicolored_lines.ipynb +++ b/docs/auto_examples/plot_multicolored_lines.ipynb @@ -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# Multicolored lines\n\nPassing continuous values (or a matrix with one row per observation) as\n`hue` together with a line format string colors each trajectory\ncontinuously along its length -- for example, coloring a trajectory by\ntime, by a behavioral variable, or by mixture proportions. Works on both\nthe matplotlib and plotly backends.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\ndata = np.cumsum(np.random.default_rng(42).standard_normal((300, 8)),\n axis=0)\n\n# color the trajectory by time\nhyp.plot(data, hue=np.arange(len(data), dtype=float))\n\n# color by any per-observation matrix (here: two smoothly varying weights)\nweights = np.column_stack([np.linspace(0, 1, len(data)),\n np.linspace(1, 0, len(data))])\nhyp.plot(data, hue=weights)" + ] + } + ], + "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# Multicolored lines\n\nPassing continuous values (or a matrix with one row per observation) as\n`hue` together with a line format string colors each trajectory\ncontinuously along its length -- for example, coloring a trajectory by\ntime, by a behavioral variable, or by mixture proportions. Works on both\nthe matplotlib and plotly backends.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\ndata = np.cumsum(np.random.default_rng(42).standard_normal((300, 8)),\n axis=0)\n\n# color the trajectory by time\nhyp.plot(data, hue=np.arange(len(data), dtype=float))\n\n# color by any per-observation matrix (here: two smoothly varying weights)\nweights = np.column_stack([np.linspace(0, 1, len(data)),\n np.linspace(1, 0, len(data))])\nhyp.plot(data, hue=weights)" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_multicolored_lines.rst b/docs/auto_examples/plot_multicolored_lines.rst index 25d7a92c..9a26d550 100644 --- a/docs/auto_examples/plot_multicolored_lines.rst +++ b/docs/auto_examples/plot_multicolored_lines.rst @@ -76,7 +76,7 @@ the matplotlib and plotly backends. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.156 seconds) + **Total running time of the script:** (0 minutes 0.113 seconds) .. _sphx_glr_download_auto_examples_plot_multicolored_lines.py: diff --git a/docs/auto_examples/plot_multicolored_lines.zip b/docs/auto_examples/plot_multicolored_lines.zip index ff3a7ce5..1676b5f7 100644 Binary files a/docs/auto_examples/plot_multicolored_lines.zip and b/docs/auto_examples/plot_multicolored_lines.zip differ diff --git a/docs/auto_examples/plot_multiindex.codeobj.json b/docs/auto_examples/plot_multiindex.codeobj.json new file mode 100644 index 00000000..173dc18a --- /dev/null +++ b/docs/auto_examples/plot_multiindex.codeobj.json @@ -0,0 +1,539 @@ +{ + "ci": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "cond": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "str" + } + ], + "data": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "df": [ + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" + } + ], + "helix": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "index": [ + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "MultiIndex" + } + ], + "n_time": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "noise": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "np.column_stack": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "column_stack" + } + ], + "np.cos": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ufunc" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "cos" + } + ], + "np.linspace": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "linspace" + } + ], + "np.pi": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "pi" + } + ], + "np.random.default_rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_2_1", + "module_short": "_cython_3_2_1", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "default_rng" + } + ], + "np.sin": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ufunc" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "sin" + } + ], + "np.vstack": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "vstack" + } + ], + "pd.DataFrame": [ + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.generic", + "module_short": "pandas.core.generic", + "name": "NDFrame" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "NDFrame" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "NDFrame" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.arraylike", + "module_short": "pandas.core.arraylike", + "name": "OpsMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "OpsMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "OpsMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.base", + "module_short": "pandas.core.base", + "name": "PandasObject" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "PandasObject" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "PandasObject" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.indexing", + "module_short": "pandas.core.indexing", + "name": "IndexingMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "IndexingMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "IndexingMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.accessor", + "module_short": "pandas.core.accessor", + "name": "DirNamesMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "DirNamesMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DirNamesMixin" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DataFrame" + } + ], + "pd.MultiIndex.from_tuples": [ + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "MultiIndex.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "Index.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.base", + "module_short": "pandas.core.base", + "name": "IndexOpsMixin.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "IndexOpsMixin.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "IndexOpsMixin.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.base", + "module_short": "pandas.core.base", + "name": "PandasObject.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "PandasObject.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "PandasObject.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.arraylike", + "module_short": "pandas.core.arraylike", + "name": "OpsMixin.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "OpsMixin.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "OpsMixin.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core.accessor", + "module_short": "pandas.core.accessor", + "name": "DirNamesMixin.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas.core", + "module_short": "pandas.core", + "name": "DirNamesMixin.from_tuples" + }, + { + "is_class": true, + "is_explicit": false, + "module": "pandas", + "module_short": "pandas", + "name": "DirNamesMixin.from_tuples" + }, + { + "is_class": false, + "is_explicit": false, + "module": "pandas.MultiIndex", + "module_short": "pandas.MultiIndex", + "name": "from_tuples" + } + ], + "rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator" + } + ], + "rng.standard_normal": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator.standard_normal" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator.standard_normal" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator.standard_normal" + } + ], + "rows": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "rows.append": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" + } + ], + "si": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "subj": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "str" + } + ], + "t": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "tuples": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "tuples.extend": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/plot_multiindex.ipynb b/docs/auto_examples/plot_multiindex.ipynb new file mode 100644 index 00000000..8602f3e2 --- /dev/null +++ b/docs/auto_examples/plot_multiindex.ipynb @@ -0,0 +1,54 @@ +{ + "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# MultiIndex DataFrames\n\nA DataFrame with a row `MultiIndex` (2 or more levels) is automatically\nexpanded by `hyp.plot` into one \"leaf\" trace per unique index combination,\nplus one thicker, more opaque \"mean\" trace per level of grouping above the\nleaves (GH #95). Color is assigned by the top-level index value; leaves\nare thin and faint, and each successive level of averaging gets a thicker\nline and higher alpha, up to a fully opaque top-level mean that also\ncarries the legend label.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nimport numpy as np\nimport pandas as pd\n\nimport hypertools as hyp\n\nrng = np.random.default_rng(3)\n\n# 2 conditions x 4 subjects, each a noisy 3D helix (offset per condition)\nn_time = 60\nt = np.linspace(0, 4 * np.pi, n_time)\ntuples, rows = [], []\nfor ci, cond in enumerate(['baseline', 'treatment']):\n for si in range(4):\n subj = f'subj{si}'\n noise = rng.standard_normal((n_time, 3)) * 0.15\n helix = np.column_stack([np.cos(t), np.sin(t), t / 4]) + noise\n helix[:, 0] += ci * 3.0\n rows.append(helix)\n tuples.extend([(cond, subj)] * n_time)\n\ndata = np.vstack(rows)\nindex = pd.MultiIndex.from_tuples(tuples, names=['condition', 'subject'])\ndf = pd.DataFrame(data, columns=['x', 'y', 'z'], index=index)\n\n# leaf traces (one per condition x subject, thin + faint) plus a thick,\n# fully opaque mean trace per condition -- colored by condition, with only\n# the condition-level means shown in the legend\nhyp.plot(df, legend=True)" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_multiindex.py b/docs/auto_examples/plot_multiindex.py new file mode 100644 index 00000000..d74d300b --- /dev/null +++ b/docs/auto_examples/plot_multiindex.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +""" +============================= +MultiIndex DataFrames +============================= + +A DataFrame with a row `MultiIndex` (2 or more levels) is automatically +expanded by `hyp.plot` into one "leaf" trace per unique index combination, +plus one thicker, more opaque "mean" trace per level of grouping above the +leaves (GH #95). Color is assigned by the top-level index value; leaves +are thin and faint, and each successive level of averaging gets a thicker +line and higher alpha, up to a fully opaque top-level mean that also +carries the legend label. +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +import numpy as np +import pandas as pd + +import hypertools as hyp + +rng = np.random.default_rng(3) + +# 2 conditions x 4 subjects, each a noisy 3D helix (offset per condition) +n_time = 60 +t = np.linspace(0, 4 * np.pi, n_time) +tuples, rows = [], [] +for ci, cond in enumerate(['baseline', 'treatment']): + for si in range(4): + subj = f'subj{si}' + noise = rng.standard_normal((n_time, 3)) * 0.15 + helix = np.column_stack([np.cos(t), np.sin(t), t / 4]) + noise + helix[:, 0] += ci * 3.0 + rows.append(helix) + tuples.extend([(cond, subj)] * n_time) + +data = np.vstack(rows) +index = pd.MultiIndex.from_tuples(tuples, names=['condition', 'subject']) +df = pd.DataFrame(data, columns=['x', 'y', 'z'], index=index) + +# leaf traces (one per condition x subject, thin + faint) plus a thick, +# fully opaque mean trace per condition -- colored by condition, with only +# the condition-level means shown in the legend +hyp.plot(df, legend=True) diff --git a/docs/auto_examples/plot_multiindex.py.md5 b/docs/auto_examples/plot_multiindex.py.md5 new file mode 100644 index 00000000..f3335c30 --- /dev/null +++ b/docs/auto_examples/plot_multiindex.py.md5 @@ -0,0 +1 @@ +ccbf86cb15d56fb49a1e12a87f4eab3f \ No newline at end of file diff --git a/docs/auto_examples/plot_multiindex.rst b/docs/auto_examples/plot_multiindex.rst new file mode 100644 index 00000000..fce6b4c1 --- /dev/null +++ b/docs/auto_examples/plot_multiindex.rst @@ -0,0 +1,110 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/plot_multiindex.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_plot_multiindex.py: + + +============================= +MultiIndex DataFrames +============================= + +A DataFrame with a row `MultiIndex` (2 or more levels) is automatically +expanded by `hyp.plot` into one "leaf" trace per unique index combination, +plus one thicker, more opaque "mean" trace per level of grouping above the +leaves (GH #95). Color is assigned by the top-level index value; leaves +are thin and faint, and each successive level of averaging gets a thicker +line and higher alpha, up to a fully opaque top-level mean that also +carries the legend label. + +.. GENERATED FROM PYTHON SOURCE LINES 15-47 + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_multiindex_001.png + :alt: plot multiindex + :srcset: /auto_examples/images/sphx_glr_plot_multiindex_001.png + :class: sphx-glr-single-img + + + + + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + import numpy as np + import pandas as pd + + import hypertools as hyp + + rng = np.random.default_rng(3) + + # 2 conditions x 4 subjects, each a noisy 3D helix (offset per condition) + n_time = 60 + t = np.linspace(0, 4 * np.pi, n_time) + tuples, rows = [], [] + for ci, cond in enumerate(['baseline', 'treatment']): + for si in range(4): + subj = f'subj{si}' + noise = rng.standard_normal((n_time, 3)) * 0.15 + helix = np.column_stack([np.cos(t), np.sin(t), t / 4]) + noise + helix[:, 0] += ci * 3.0 + rows.append(helix) + tuples.extend([(cond, subj)] * n_time) + + data = np.vstack(rows) + index = pd.MultiIndex.from_tuples(tuples, names=['condition', 'subject']) + df = pd.DataFrame(data, columns=['x', 'y', 'z'], index=index) + + # leaf traces (one per condition x subject, thin + faint) plus a thick, + # fully opaque mean trace per condition -- colored by condition, with only + # the condition-level means shown in the legend + hyp.plot(df, legend=True) + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 0.052 seconds) + + +.. _sphx_glr_download_auto_examples_plot_multiindex.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: plot_multiindex.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: plot_multiindex.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: plot_multiindex.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/plot_multiindex.zip b/docs/auto_examples/plot_multiindex.zip new file mode 100644 index 00000000..a23c964d Binary files /dev/null and b/docs/auto_examples/plot_multiindex.zip differ diff --git a/docs/auto_examples/plot_nested_lists.ipynb b/docs/auto_examples/plot_nested_lists.ipynb index 175c899e..23700d28 100644 --- a/docs/auto_examples/plot_nested_lists.ipynb +++ b/docs/auto_examples/plot_nested_lists.ipynb @@ -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# Nested lists and multilevel styling\n\nhypertools 1.0 accepts arbitrarily nested lists of datasets. Every dataset\nunder the same outermost group shares that group's color, and each\nadditional nesting level renders with thinner, fainter lines -- a\nsummary-to-detail visual hierarchy. For example, `[[a, b], [c]]` colors\n`a` and `b` alike (group 1) and `c` differently (group 2).\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\n\ndef walk(seed):\n return np.cumsum(np.random.default_rng(seed).standard_normal((150, 6)),\n axis=0)\n\n\n# two groups: [a, b] vs [c] -- a and b share a color\nhyp.plot([[walk(0), walk(1)], [walk(2)]])\n\n# mixed depth: deeper leaves render thinner and fainter\nhyp.plot([[walk(0), [walk(1)]], walk(2)])" + ] + } + ], + "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# Nested lists and multilevel styling\n\nhypertools 2.0 accepts arbitrarily nested lists of datasets. Every dataset\nunder the same outermost group shares that group's color, and each\nadditional nesting level renders with thinner, fainter lines -- a\nsummary-to-detail visual hierarchy. For example, `[[a, b], [c]]` colors\n`a` and `b` alike (group 1) and `c` differently (group 2).\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Contextual Dynamics Lab\n# License: MIT\n\nimport numpy as np\nimport hypertools as hyp\n\n\ndef walk(seed):\n return np.cumsum(np.random.default_rng(seed).standard_normal((150, 6)),\n axis=0)\n\n\n# two groups: [a, b] vs [c] -- a and b share a color\nhyp.plot([[walk(0), walk(1)], [walk(2)]])\n\n# mixed depth: deeper leaves render thinner and fainter\nhyp.plot([[walk(0), [walk(1)]], walk(2)])" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_nested_lists.py b/docs/auto_examples/plot_nested_lists.py index e9b17534..903d1d30 100644 --- a/docs/auto_examples/plot_nested_lists.py +++ b/docs/auto_examples/plot_nested_lists.py @@ -4,7 +4,7 @@ Nested lists and multilevel styling ============================= -hypertools 2.0 accepts arbitrarily nested lists of datasets. Every dataset +hypertools 1.0 accepts arbitrarily nested lists of datasets. Every dataset under the same outermost group shares that group's color, and each additional nesting level renders with thinner, fainter lines -- a summary-to-detail visual hierarchy. For example, `[[a, b], [c]]` colors diff --git a/docs/auto_examples/plot_nested_lists.py.md5 b/docs/auto_examples/plot_nested_lists.py.md5 index 9976d27a..a2d2ac4f 100644 --- a/docs/auto_examples/plot_nested_lists.py.md5 +++ b/docs/auto_examples/plot_nested_lists.py.md5 @@ -1 +1 @@ -d744f80445d2702d7cd7a5e566e788c4 \ No newline at end of file +85b078fb4de701704f5ba9f78dd350e9 \ No newline at end of file diff --git a/docs/auto_examples/plot_nested_lists.rst b/docs/auto_examples/plot_nested_lists.rst index c630a8a8..7c667032 100644 --- a/docs/auto_examples/plot_nested_lists.rst +++ b/docs/auto_examples/plot_nested_lists.rst @@ -22,7 +22,7 @@ Nested lists and multilevel styling ============================= -hypertools 2.0 accepts arbitrarily nested lists of datasets. Every dataset +hypertools 1.0 accepts arbitrarily nested lists of datasets. Every dataset under the same outermost group shares that group's color, and each additional nesting level renders with thinner, fainter lines -- a summary-to-detail visual hierarchy. For example, `[[a, b], [c]]` colors @@ -77,7 +77,7 @@ summary-to-detail visual hierarchy. For example, `[[a, b], [c]]` colors .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.224 seconds) + **Total running time of the script:** (0 minutes 0.123 seconds) .. _sphx_glr_download_auto_examples_plot_nested_lists.py: diff --git a/docs/auto_examples/plot_nested_lists.zip b/docs/auto_examples/plot_nested_lists.zip index 70b594c4..136cd48e 100644 Binary files a/docs/auto_examples/plot_nested_lists.zip and b/docs/auto_examples/plot_nested_lists.zip differ diff --git a/docs/auto_examples/plot_normalize.ipynb b/docs/auto_examples/plot_normalize.ipynb index 50b190ce..375b74ea 100644 --- a/docs/auto_examples/plot_normalize.ipynb +++ b/docs/auto_examples/plot_normalize.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Normalizing your features\n\nOften times its useful to normalize (z-score) you features before plotting, so\nthat they are on the same scale. Otherwise, some features will be weighted more\nheavily than others when doing PCA, and that may or may not be what you want.\nThe `normalize` kwarg can be passed to the plot function. If `normalize` is\nset to 'across', the zscore will be computed for the column across all of the\nlists passed. Conversely, if `normalize` is set to 'within', the z-score will\nbe computed separately for each column in each list. Finally, if `normalize` is\nset to 'row', each row of the matrix will be zscored. Alternatively, you can use\nthe normalize function found in tools (see the third example).\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# simulate data\ncluster1 = np.random.multivariate_normal(np.zeros(3), np.eye(3), size=100)\ncluster2 = np.random.multivariate_normal(np.zeros(3)+10, np.eye(3), size=100)\ndata = [cluster1, cluster2]\n\n# plot normalized across lists\nhyp.plot(data, '.', normalize='across', title='Normalized across datasets')\n\n# plot normalized within list\nhyp.plot(data, '.', normalize='within', title='Normalized within dataset')\n\n# normalize by row\nnormalized_row = hyp.normalize(data, normalize='row')\n\n# plot normalized by row\nhyp.plot(normalized_row, '.', title='Normalized across row')" + ] + } + ], + "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# Normalizing your features\n\nOften times its useful to normalize (z-score) you features before plotting, so\nthat they are on the same scale. Otherwise, some features will be weighted more\nheavily than others when doing PCA, and that may or may not be what you want.\nThe `normalize` kwarg can be passed to the plot function. If `normalize` is\nset to 'across', the zscore will be computed for the column across all of the\nlists passed. Conversely, if `normalize` is set to 'within', the z-score will\nbe computed separately for each column in each list. Finally, if `normalize` is\nset to 'row', each row of the matrix will be zscored. Alternatively, you can use\nthe normalize function found in tools (see the third example).\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# simulate data\ncluster1 = np.random.multivariate_normal(np.zeros(3), np.eye(3), size=100)\ncluster2 = np.random.multivariate_normal(np.zeros(3)+10, np.eye(3), size=100)\ndata = [cluster1, cluster2]\n\n# plot normalized across lists\nhyp.plot(data, '.', normalize='across', title='Normalized across datasets')\n\n# plot normalized within list\nhyp.plot(data, '.', normalize='within', title='Normalized within dataset')\n\n# normalize by row\nnormalized_row = hyp.normalize(data, normalize='row')\n\n# plot normalized by row\nhyp.plot(normalized_row, '.', title='Normalized across row')" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_normalize.rst b/docs/auto_examples/plot_normalize.rst index c290a897..0a39161e 100644 --- a/docs/auto_examples/plot_normalize.rst +++ b/docs/auto_examples/plot_normalize.rst @@ -61,19 +61,9 @@ the normalize function found in tools (see the third example). :class: sphx-glr-multi-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - - - - - - -| - .. code-block:: Python @@ -105,7 +95,7 @@ the normalize function found in tools (see the third example). .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.079 seconds) + **Total running time of the script:** (0 minutes 0.061 seconds) .. _sphx_glr_download_auto_examples_plot_normalize.py: diff --git a/docs/auto_examples/plot_normalize.zip b/docs/auto_examples/plot_normalize.zip index f6ed7b97..090c3364 100644 Binary files a/docs/auto_examples/plot_normalize.zip and b/docs/auto_examples/plot_normalize.zip differ diff --git a/docs/auto_examples/plot_predict.codeobj.json b/docs/auto_examples/plot_predict.codeobj.json new file mode 100644 index 00000000..ace9a3b5 --- /dev/null +++ b/docs/auto_examples/plot_predict.codeobj.json @@ -0,0 +1,157 @@ +{ + "data": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "helix": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "np.column_stack": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "column_stack" + } + ], + "np.cos": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ufunc" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "cos" + } + ], + "np.linspace": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "linspace" + } + ], + "np.pi": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "pi" + } + ], + "np.random.randn": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "module.randn" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "randn" + } + ], + "np.random.seed": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_2_1", + "module_short": "_cython_3_2_1", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "seed" + } + ], + "np.sin": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ufunc" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "sin" + } + ], + "ts": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/plot_predict.ipynb b/docs/auto_examples/plot_predict.ipynb new file mode 100644 index 00000000..4b7866dc --- /dev/null +++ b/docs/auto_examples/plot_predict.ipynb @@ -0,0 +1,54 @@ +{ + "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# Forecasting timeseries with predict\n\nThe `predict` kwarg overlays a forecast on top of your plotted data: a\ndashed, same-color tail extending `t` steps past the end of each dataset.\nUnder the hood this calls `hypertools.predict`, which supports several\nforecasting models -- `'Kalman'` (a linear-Gaussian state-space filter,\nused here), `'GaussianProcess'`, `'AutoRegressor'` (any sklearn regressor\nrun recursively), `'ARIMA'`, `'Laplace'`, and `'Chronos'` (a HuggingFace\ntime-series foundation model) -- selected via `model=` when calling\n`hypertools.predict` directly. Calling `hyp.predict(data, model=...,\nt=..., return_model=True)` also returns the fitted forecaster alongside\nthe forecast, so the same fitted model can be reused (without\nre-estimating) on new data.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\n# import\nimport numpy as np\nimport hypertools as hyp\n\n# simulate two noisy 5D helical trajectories (phase-shifted): structured\n# dynamics like these make the forecast visible -- the dashed tail continues\n# each spiral's sweep. (Aperiodic data such as random walks are forecastable\n# too, but their best forecast is nearly constant, which is less fun to look\n# at.)\nnp.random.seed(1234)\nts = np.linspace(0, 4 * np.pi, 90)\n\n\ndef helix(phase):\n clean = np.column_stack([\n np.cos(ts + phase), np.sin(ts + phase), ts / 4,\n 0.5 * np.cos(2 * ts + phase), 0.5 * np.sin(2 * ts + phase)])\n return clean + np.random.randn(*clean.shape) * 0.03\n\n\ndata = [helix(0.0), helix(2.0)]\n\n# plot, forecasting 30 steps ahead with a Gaussian process; the dashed,\n# same-color tails are the forecasts\nhyp.plot(data, predict='GaussianProcess', t=30,\n legend=['helix 1', 'helix 2'], linewidth=2)" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_predict.py b/docs/auto_examples/plot_predict.py new file mode 100644 index 00000000..bf88cd84 --- /dev/null +++ b/docs/auto_examples/plot_predict.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +""" +============================= +Forecasting timeseries with predict +============================= + +The `predict` kwarg overlays a forecast on top of your plotted data: a +dashed, same-color tail extending `t` steps past the end of each dataset. +Under the hood this calls `hypertools.predict`, which supports several +forecasting models -- `'Kalman'` (a linear-Gaussian state-space filter, +used here), `'GaussianProcess'`, `'AutoRegressor'` (any sklearn regressor +run recursively), `'ARIMA'`, `'Laplace'`, and `'Chronos'` (a HuggingFace +time-series foundation model) -- selected via `model=` when calling +`hypertools.predict` directly. Calling `hyp.predict(data, model=..., +t=..., return_model=True)` also returns the fitted forecaster alongside +the forecast, so the same fitted model can be reused (without +re-estimating) on new data. +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +# import +import numpy as np +import hypertools as hyp + +# simulate two noisy 5D helical trajectories (phase-shifted): structured +# dynamics like these make the forecast visible -- the dashed tail continues +# each spiral's sweep. (Aperiodic data such as random walks are forecastable +# too, but their best forecast is nearly constant, which is less fun to look +# at.) +np.random.seed(1234) +ts = np.linspace(0, 4 * np.pi, 90) + + +def helix(phase): + clean = np.column_stack([ + np.cos(ts + phase), np.sin(ts + phase), ts / 4, + 0.5 * np.cos(2 * ts + phase), 0.5 * np.sin(2 * ts + phase)]) + return clean + np.random.randn(*clean.shape) * 0.03 + + +data = [helix(0.0), helix(2.0)] + +# plot, forecasting 30 steps ahead with a Gaussian process; the dashed, +# same-color tails are the forecasts +hyp.plot(data, predict='GaussianProcess', t=30, + legend=['helix 1', 'helix 2'], linewidth=2) diff --git a/docs/auto_examples/plot_predict.py.md5 b/docs/auto_examples/plot_predict.py.md5 new file mode 100644 index 00000000..a493aa9d --- /dev/null +++ b/docs/auto_examples/plot_predict.py.md5 @@ -0,0 +1 @@ +1f8b4eaac0bb1c1eb4ad08f7f198b9cf \ No newline at end of file diff --git a/docs/auto_examples/plot_predict.rst b/docs/auto_examples/plot_predict.rst new file mode 100644 index 00000000..e07aedac --- /dev/null +++ b/docs/auto_examples/plot_predict.rst @@ -0,0 +1,112 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/plot_predict.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_plot_predict.py: + + +============================= +Forecasting timeseries with predict +============================= + +The `predict` kwarg overlays a forecast on top of your plotted data: a +dashed, same-color tail extending `t` steps past the end of each dataset. +Under the hood this calls `hypertools.predict`, which supports several +forecasting models -- `'Kalman'` (a linear-Gaussian state-space filter, +used here), `'GaussianProcess'`, `'AutoRegressor'` (any sklearn regressor +run recursively), `'ARIMA'`, `'Laplace'`, and `'Chronos'` (a HuggingFace +time-series foundation model) -- selected via `model=` when calling +`hypertools.predict` directly. Calling `hyp.predict(data, model=..., +t=..., return_model=True)` also returns the fitted forecaster alongside +the forecast, so the same fitted model can be reused (without +re-estimating) on new data. + +.. GENERATED FROM PYTHON SOURCE LINES 19-49 + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_predict_001.png + :alt: plot predict + :srcset: /auto_examples/images/sphx_glr_plot_predict_001.png + :class: sphx-glr-single-img + + + + + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + # import + import numpy as np + import hypertools as hyp + + # simulate two noisy 5D helical trajectories (phase-shifted): structured + # dynamics like these make the forecast visible -- the dashed tail continues + # each spiral's sweep. (Aperiodic data such as random walks are forecastable + # too, but their best forecast is nearly constant, which is less fun to look + # at.) + np.random.seed(1234) + ts = np.linspace(0, 4 * np.pi, 90) + + + def helix(phase): + clean = np.column_stack([ + np.cos(ts + phase), np.sin(ts + phase), ts / 4, + 0.5 * np.cos(2 * ts + phase), 0.5 * np.sin(2 * ts + phase)]) + return clean + np.random.randn(*clean.shape) * 0.03 + + + data = [helix(0.0), helix(2.0)] + + # plot, forecasting 30 steps ahead with a Gaussian process; the dashed, + # same-color tails are the forecasts + hyp.plot(data, predict='GaussianProcess', t=30, + legend=['helix 1', 'helix 2'], linewidth=2) + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 0.217 seconds) + + +.. _sphx_glr_download_auto_examples_plot_predict.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: plot_predict.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: plot_predict.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: plot_predict.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/plot_predict.zip b/docs/auto_examples/plot_predict.zip new file mode 100644 index 00000000..1b4407f4 Binary files /dev/null and b/docs/auto_examples/plot_predict.zip differ diff --git a/docs/auto_examples/plot_procrustes.codeobj.json b/docs/auto_examples/plot_procrustes.codeobj.json index 4936c9af..8d43b776 100644 --- a/docs/auto_examples/plot_procrustes.codeobj.json +++ b/docs/auto_examples/plot_procrustes.codeobj.json @@ -8,52 +8,13 @@ "name": "list" } ], - "geo": [ + "data": [ { "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" - } - ], - "geo.plot": [ - { - "is_class": false, - "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" - }, - { - "is_class": false, - "is_explicit": false, - "module": "hypertools", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], "hyp.load": [ @@ -88,7 +49,7 @@ "name": "plot" } ], - "hyp.tools.procrustes": [ + "procrustes": [ { "is_class": false, "is_explicit": false, @@ -99,8 +60,8 @@ { "is_class": false, "is_explicit": false, - "module": "hypertools.tools", - "module_short": "hypertools.tools", + "module": "hypertools.align.procrustes", + "module_short": "hypertools.align", "name": "procrustes" } ], diff --git a/docs/auto_examples/plot_procrustes.ipynb b/docs/auto_examples/plot_procrustes.ipynb index ffe2bc2e..7994fc51 100644 --- a/docs/auto_examples/plot_procrustes.ipynb +++ b/docs/auto_examples/plot_procrustes.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Aligning two matrices with the procrustes function\n\nIn this example, we load in some synthetic data, rotate it, and then use the\nprocustes function to get the datasets back in alignment. The procrustes\nfunction uses linear transformations to project a source matrix into the\nspace of a target matrix.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\nimport scipy\nfrom hypertools.align.procrustes import procrustes\n\n# load example data\ndata = hyp.load('spiral')\nhyp.plot(data, title='Before Alignment')\n\n# use procrusted to align the data\nsource, target = data\naligned = [procrustes(source, target), target]\n\n# after alignment\nhyp.plot(aligned, ['-','--'], title='After alignment')" + ] + } + ], + "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# Aligning two matrices with the procrustes function\n\nIn this example, we load in some synthetic data, rotate it, and then use the\nprocustes function to get the datasets back in alignment. The procrustes\nfunction uses linear transformations to project a source matrix into the\nspace of a target matrix.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\nimport scipy\n\n# load example data\ngeo = hyp.load('spiral')\ngeo.plot(title='Before Alignment')\n\n# use procrusted to align the data\nsource, target = geo.get_data()\naligned = [hyp.tools.procrustes(source, target), target]\n\n# after alignment\nhyp.plot(aligned, ['-','--'], title='After alignment')" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_procrustes.py b/docs/auto_examples/plot_procrustes.py index 5f1ff0fb..e8e11050 100644 --- a/docs/auto_examples/plot_procrustes.py +++ b/docs/auto_examples/plot_procrustes.py @@ -17,14 +17,15 @@ import hypertools as hyp import numpy as np import scipy +from hypertools.align.procrustes import procrustes # load example data -geo = hyp.load('spiral') -geo.plot(title='Before Alignment') +data = hyp.load('spiral') +hyp.plot(data, title='Before Alignment') # use procrusted to align the data -source, target = geo.get_data() -aligned = [hyp.tools.procrustes(source, target), target] +source, target = data +aligned = [procrustes(source, target), target] # after alignment hyp.plot(aligned, ['-','--'], title='After alignment') diff --git a/docs/auto_examples/plot_procrustes.py.md5 b/docs/auto_examples/plot_procrustes.py.md5 index a64107b3..2f14e520 100644 --- a/docs/auto_examples/plot_procrustes.py.md5 +++ b/docs/auto_examples/plot_procrustes.py.md5 @@ -1 +1 @@ -4ab27ff9342adf4968d19302c28b3591 \ No newline at end of file +bccb61e01d3e4161f4e2c7a65ec18ee0 \ No newline at end of file diff --git a/docs/auto_examples/plot_procrustes.rst b/docs/auto_examples/plot_procrustes.rst index 4b28ddfe..05907cfe 100644 --- a/docs/auto_examples/plot_procrustes.rst +++ b/docs/auto_examples/plot_procrustes.rst @@ -27,7 +27,7 @@ procustes function to get the datasets back in alignment. The procrustes function uses linear transformations to project a source matrix into the space of a target matrix. -.. GENERATED FROM PYTHON SOURCE LINES 12-31 +.. GENERATED FROM PYTHON SOURCE LINES 12-32 @@ -49,19 +49,9 @@ space of a target matrix. :class: sphx-glr-multi-img -.. rst-class:: sphx-glr-script-out - .. code-block:: none - - - - - - -| - .. code-block:: Python @@ -72,14 +62,15 @@ space of a target matrix. import hypertools as hyp import numpy as np import scipy + from hypertools.align.procrustes import procrustes # load example data - geo = hyp.load('spiral') - geo.plot(title='Before Alignment') + data = hyp.load('spiral') + hyp.plot(data, title='Before Alignment') # use procrusted to align the data - source, target = geo.get_data() - aligned = [hyp.tools.procrustes(source, target), target] + source, target = data + aligned = [procrustes(source, target), target] # after alignment hyp.plot(aligned, ['-','--'], title='After alignment') @@ -87,7 +78,7 @@ space of a target matrix. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.047 seconds) + **Total running time of the script:** (0 minutes 0.043 seconds) .. _sphx_glr_download_auto_examples_plot_procrustes.py: diff --git a/docs/auto_examples/plot_procrustes.zip b/docs/auto_examples/plot_procrustes.zip index 5453640a..e0ca4428 100644 Binary files a/docs/auto_examples/plot_procrustes.zip and b/docs/auto_examples/plot_procrustes.zip differ diff --git a/docs/auto_examples/plot_shape_morph.codeobj.json b/docs/auto_examples/plot_shape_morph.codeobj.json new file mode 100644 index 00000000..8e43f6cc --- /dev/null +++ b/docs/auto_examples/plot_shape_morph.codeobj.json @@ -0,0 +1,185 @@ +{ + "ani": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.animation", + "module_short": "matplotlib.animation", + "name": "FuncAnimation" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "FuncAnimation" + } + ], + "clouds": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "fig": [ + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure" + } + ], + "hyp.load": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "load" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "normalize_shape": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + } + ], + "np.abs": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ufunc" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "abs" + } + ], + "np.asarray": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "asarray" + } + ], + "np.float64": [ + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "float64" + }, + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "floating" + }, + { + "is_class": true, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + }, + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "inexact" + }, + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "number" + }, + { + "is_class": true, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "generic" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "float64" + } + ], + "rotations": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "shapes": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/plot_shape_morph.ipynb b/docs/auto_examples/plot_shape_morph.ipynb new file mode 100644 index 00000000..332a243b --- /dev/null +++ b/docs/auto_examples/plot_shape_morph.ipynb @@ -0,0 +1,54 @@ +{ + "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# Morphing through the shapes zoo\n\nHyperTools' \"shapes zoo\" (bunny, cube, dragon, sphere, teapot, vase,\nbiplane -- see the *A zoo of 3D shapes* example) can be morphed smoothly\nfrom one point cloud to the next with the ``animate='morph'`` `hyp.plot`\nstyle (PR #272, maintainer request 2026-07-06 -- see the `animate`/\n`rotations`/`morph_samples` entries of the `hyp.plot` docstring for the\nfull spec). Under the hood, every shape keeps its own full point count by\ndefault (smaller shapes are padded up to the largest shape's count by\nduplicating random points of their own) -- but the zoo's shapes range up\nto ~90,000 points (the biplane), and the Hungarian assignment used to\nmatch consecutive shapes point-for-point is roughly ``O(n^3)``, so\n`morph_samples=1000` below first downsamples every shape to a tractable\n1000 points (build-time: the full, uncapped 90k-point target would make\nthe matching step infeasible for a gallery build). Consecutive shapes are\nmatched point-for-point with the Hungarian algorithm\n(`scipy.optimize.linear_sum_assignment`) so that each point travels the\nshortest total distance to its partner in the next shape, and the\ncoordinates are eased between shapes frame by frame while the camera\nspins around the scene -- exactly the hand-rolled recipe this example\nused to implement itself before `animate='morph'` existed, now built into\nthe library behind a single `hyp.plot` call. `rotations` also\naccepts a per-segment list for finer camera control: below, holds spin a\nslow, easy-to-watch full rotation while each transition only spins a\nbrisk quarter-turn, so the camera visibly \"steps\" forward every time one\nshape morphs into the next. Camera speed (degrees/frame) is always\nCONSTANT across the whole animation -- a segment's `rotations` entry sets\nhow much SCREEN TIME it gets, not how fast it spins, so the full-rotation\nholds below play roughly 4x longer than the quarter-turn transitions\n(1 / 0.25), never faster.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nimport numpy as np\n\nimport hypertools as hyp\n\n# every point cloud in the shapes zoo, visited in this order\nshapes = ['bunny', 'cube', 'dragon', 'sphere', 'teapot', 'vase', 'biplane']\n\n\ndef normalize_shape(points):\n \"\"\"Center and scale a point cloud into the hypertools [-1, 1] cube.\"\"\"\n points = np.asarray(points, dtype=np.float64)\n points = points - points.mean(axis=0)\n return points / np.abs(points).max()\n\n\nclouds = [normalize_shape(hyp.load(shape)) for shape in shapes]\n\n# frame schedule: hold, morph, hold, morph, ..., hold -- 2 * n_shapes - 1 =\n# 13 segments in all. `rotations` gives each segment its OWN camera-spin\n# count: holds get a slow, easy-to-watch full rotation (1) while\n# transitions get a brisk quarter-turn (0.25), so the camera visibly steps\n# forward every time a shape morphs into the next one. Camera speed stays\n# CONSTANT (degrees/frame) across the whole animation, so each segment's\n# SCREEN TIME is now proportional to its own rotation count -- the 7\n# full-rotation holds get ~46 frames each and the 6 quarter-turn\n# transitions get ~11-12 frames each (390 frames total @ 30 fps, ~13 sec,\n# same total length as an equal-time split would have given).\nrotations = [1, 0.25] * (len(shapes) - 1) + [1]\n\n# morph_samples=1000: caps every shape at 1000 points (build tractability --\n# see module docstring) before the Hungarian matching step.\nfig, ani = hyp.plot(clouds, fmt='.', color='k', markersize=1.5,\n animate='morph', rotations=rotations,\n morph_samples=1000,\n duration=len(rotations), frame_rate=30)" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_shape_morph.py b/docs/auto_examples/plot_shape_morph.py new file mode 100644 index 00000000..776611de --- /dev/null +++ b/docs/auto_examples/plot_shape_morph.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +""" +================================ +Morphing through the shapes zoo +================================ + +HyperTools' "shapes zoo" (bunny, cube, dragon, sphere, teapot, vase, +biplane -- see the *A zoo of 3D shapes* example) can be morphed smoothly +from one point cloud to the next with the ``animate='morph'`` `hyp.plot` +style (PR #272, maintainer request 2026-07-06 -- see the `animate`/ +`rotations`/`morph_samples` entries of the `hyp.plot` docstring for the +full spec). Under the hood, every shape keeps its own full point count by +default (smaller shapes are padded up to the largest shape's count by +duplicating random points of their own) -- but the zoo's shapes range up +to ~90,000 points (the biplane), and the Hungarian assignment used to +match consecutive shapes point-for-point is roughly ``O(n^3)``, so +`morph_samples=1000` below first downsamples every shape to a tractable +1000 points (build-time: the full, uncapped 90k-point target would make +the matching step infeasible for a gallery build). Consecutive shapes are +matched point-for-point with the Hungarian algorithm +(`scipy.optimize.linear_sum_assignment`) so that each point travels the +shortest total distance to its partner in the next shape, and the +coordinates are eased between shapes frame by frame while the camera +spins around the scene -- exactly the hand-rolled recipe this example +used to implement itself before `animate='morph'` existed, now built into +the library behind a single `hyp.plot` call. `rotations` also +accepts a per-segment list for finer camera control: below, holds spin a +slow, easy-to-watch full rotation while each transition only spins a +brisk quarter-turn, so the camera visibly "steps" forward every time one +shape morphs into the next. Camera speed (degrees/frame) is always +CONSTANT across the whole animation -- a segment's `rotations` entry sets +how much SCREEN TIME it gets, not how fast it spins, so the full-rotation +holds below play roughly 4x longer than the quarter-turn transitions +(1 / 0.25), never faster. +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +import numpy as np + +import hypertools as hyp + +# every point cloud in the shapes zoo, visited in this order +shapes = ['bunny', 'cube', 'dragon', 'sphere', 'teapot', 'vase', 'biplane'] + + +def normalize_shape(points): + """Center and scale a point cloud into the hypertools [-1, 1] cube.""" + points = np.asarray(points, dtype=np.float64) + points = points - points.mean(axis=0) + return points / np.abs(points).max() + + +clouds = [normalize_shape(hyp.load(shape)) for shape in shapes] + +# frame schedule: hold, morph, hold, morph, ..., hold -- 2 * n_shapes - 1 = +# 13 segments in all. `rotations` gives each segment its OWN camera-spin +# count: holds get a slow, easy-to-watch full rotation (1) while +# transitions get a brisk quarter-turn (0.25), so the camera visibly steps +# forward every time a shape morphs into the next one. Camera speed stays +# CONSTANT (degrees/frame) across the whole animation, so each segment's +# SCREEN TIME is now proportional to its own rotation count -- the 7 +# full-rotation holds get ~46 frames each and the 6 quarter-turn +# transitions get ~11-12 frames each (390 frames total @ 30 fps, ~13 sec, +# same total length as an equal-time split would have given). +rotations = [1, 0.25] * (len(shapes) - 1) + [1] + +# morph_samples=1000: caps every shape at 1000 points (build tractability -- +# see module docstring) before the Hungarian matching step. +fig, ani = hyp.plot(clouds, fmt='.', color='k', markersize=1.5, + animate='morph', rotations=rotations, + morph_samples=1000, + duration=len(rotations), frame_rate=30) diff --git a/docs/auto_examples/plot_shape_morph.py.md5 b/docs/auto_examples/plot_shape_morph.py.md5 new file mode 100644 index 00000000..45631b18 --- /dev/null +++ b/docs/auto_examples/plot_shape_morph.py.md5 @@ -0,0 +1 @@ +7a482a52efd4c7d56ab9993179021905 \ No newline at end of file diff --git a/docs/auto_examples/plot_shape_morph.rst b/docs/auto_examples/plot_shape_morph.rst new file mode 100644 index 00000000..b26a90c2 --- /dev/null +++ b/docs/auto_examples/plot_shape_morph.rst @@ -0,0 +1,140 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/plot_shape_morph.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_plot_shape_morph.py: + + +================================ +Morphing through the shapes zoo +================================ + +HyperTools' "shapes zoo" (bunny, cube, dragon, sphere, teapot, vase, +biplane -- see the *A zoo of 3D shapes* example) can be morphed smoothly +from one point cloud to the next with the ``animate='morph'`` `hyp.plot` +style (PR #272, maintainer request 2026-07-06 -- see the `animate`/ +`rotations`/`morph_samples` entries of the `hyp.plot` docstring for the +full spec). Under the hood, every shape keeps its own full point count by +default (smaller shapes are padded up to the largest shape's count by +duplicating random points of their own) -- but the zoo's shapes range up +to ~90,000 points (the biplane), and the Hungarian assignment used to +match consecutive shapes point-for-point is roughly ``O(n^3)``, so +`morph_samples=1000` below first downsamples every shape to a tractable +1000 points (build-time: the full, uncapped 90k-point target would make +the matching step infeasible for a gallery build). Consecutive shapes are +matched point-for-point with the Hungarian algorithm +(`scipy.optimize.linear_sum_assignment`) so that each point travels the +shortest total distance to its partner in the next shape, and the +coordinates are eased between shapes frame by frame while the camera +spins around the scene -- exactly the hand-rolled recipe this example +used to implement itself before `animate='morph'` existed, now built into +the library behind a single `hyp.plot` call. `rotations` also +accepts a per-segment list for finer camera control: below, holds spin a +slow, easy-to-watch full rotation while each transition only spins a +brisk quarter-turn, so the camera visibly "steps" forward every time one +shape morphs into the next. Camera speed (degrees/frame) is always +CONSTANT across the whole animation -- a segment's `rotations` entry sets +how much SCREEN TIME it gets, not how fast it spins, so the full-rotation +holds below play roughly 4x longer than the quarter-turn transitions +(1 / 0.25), never faster. + +.. GENERATED FROM PYTHON SOURCE LINES 36-75 + + + +.. video:: /auto_examples/images/sphx_glr_plot_shape_morph_001.mp4 + :class: sphx-glr-single-img + :height: 480 + :width: 640 + :autoplay: + + + + + + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + import numpy as np + + import hypertools as hyp + + # every point cloud in the shapes zoo, visited in this order + shapes = ['bunny', 'cube', 'dragon', 'sphere', 'teapot', 'vase', 'biplane'] + + + def normalize_shape(points): + """Center and scale a point cloud into the hypertools [-1, 1] cube.""" + points = np.asarray(points, dtype=np.float64) + points = points - points.mean(axis=0) + return points / np.abs(points).max() + + + clouds = [normalize_shape(hyp.load(shape)) for shape in shapes] + + # frame schedule: hold, morph, hold, morph, ..., hold -- 2 * n_shapes - 1 = + # 13 segments in all. `rotations` gives each segment its OWN camera-spin + # count: holds get a slow, easy-to-watch full rotation (1) while + # transitions get a brisk quarter-turn (0.25), so the camera visibly steps + # forward every time a shape morphs into the next one. Camera speed stays + # CONSTANT (degrees/frame) across the whole animation, so each segment's + # SCREEN TIME is now proportional to its own rotation count -- the 7 + # full-rotation holds get ~46 frames each and the 6 quarter-turn + # transitions get ~11-12 frames each (390 frames total @ 30 fps, ~13 sec, + # same total length as an equal-time split would have given). + rotations = [1, 0.25] * (len(shapes) - 1) + [1] + + # morph_samples=1000: caps every shape at 1000 points (build tractability -- + # see module docstring) before the Hungarian matching step. + fig, ani = hyp.plot(clouds, fmt='.', color='k', markersize=1.5, + animate='morph', rotations=rotations, + morph_samples=1000, + duration=len(rotations), frame_rate=30) + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 3.598 seconds) + + +.. _sphx_glr_download_auto_examples_plot_shape_morph.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: plot_shape_morph.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: plot_shape_morph.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: plot_shape_morph.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/plot_shape_morph.zip b/docs/auto_examples/plot_shape_morph.zip new file mode 100644 index 00000000..8a96394f Binary files /dev/null and b/docs/auto_examples/plot_shape_morph.zip differ diff --git a/docs/auto_examples/plot_shapes_zoo.ipynb b/docs/auto_examples/plot_shapes_zoo.ipynb index 8c011f91..2a57fa6f 100644 --- a/docs/auto_examples/plot_shapes_zoo.ipynb +++ b/docs/auto_examples/plot_shapes_zoo.ipynb @@ -8,7 +8,7 @@ }, "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" + "# 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" ] }, { diff --git a/docs/auto_examples/plot_shapes_zoo.rst b/docs/auto_examples/plot_shapes_zoo.rst index fbdf733e..7496046e 100644 --- a/docs/auto_examples/plot_shapes_zoo.rst +++ b/docs/auto_examples/plot_shapes_zoo.rst @@ -78,7 +78,7 @@ pre-created 3D axes to `hyp.plot` via the `ax` keyword. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.224 seconds) + **Total running time of the script:** (0 minutes 0.226 seconds) .. _sphx_glr_download_auto_examples_plot_shapes_zoo.py: diff --git a/docs/auto_examples/plot_shapes_zoo.zip b/docs/auto_examples/plot_shapes_zoo.zip index 449d522b..090153c2 100644 Binary files a/docs/auto_examples/plot_shapes_zoo.zip and b/docs/auto_examples/plot_shapes_zoo.zip differ diff --git a/docs/auto_examples/plot_sotus.ipynb b/docs/auto_examples/plot_sotus.ipynb index 2d9cac02..361cc675 100644 --- a/docs/auto_examples/plot_sotus.ipynb +++ b/docs/auto_examples/plot_sotus.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Plotting State of the Union Addresses with Text Analysis\n\nThis example demonstrates how to plot text data using hypertools. We create\nsample State of the Union address excerpts covering different political themes\nand visualize them in a reduced dimensional space. By default, hypertools \ntransforms the text data using a topic model to capture semantic relationships \nbetween different speech segments.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# load hypertools\nimport hypertools as hyp\n\n# load the data\n# Note: 'sotus' loads a text processing model, not the actual SOTU speeches\n# We'll create sample text data to demonstrate text plotting capabilities\nprint(\"Creating sample State of the Union demonstration...\")\n\n# Sample State of the Union excerpts for demonstration\nsample_speeches = [\n \"Tonight I can report to the nation that America is stronger, America is more secure, and America is respected again. After years of decline, our economy is growing again.\",\n \"We gather tonight knowing that this generation of Americans has been tested by crisis and proven worthy of our founding principles. The state of our union is strong.\",\n \"As we work together to advance America's interests, we must also recognize the threats we face. We will rebuild our military and defend our nation.\",\n \"Education is the great equalizer in America. We must ensure every child has access to quality education regardless of their zip code.\",\n \"Healthcare should be affordable and accessible to all Americans. We will work to reduce costs while maintaining quality care.\",\n \"We must secure our borders and have an immigration system that works for America and reflects our values.\",\n \"Innovation and technology will drive America forward in the 21st century. We must invest in research and development.\",\n \"Climate change poses real challenges, and we will address them with American innovation and determination.\",\n \"Our military is the finest in the world, and we will ensure our veterans receive the care they have earned.\",\n \"The economy is strong, unemployment is low, and American families are prospering like never before.\"\n]\n\n# Add labels for the different themes\nlabels = ['Security', 'Unity', 'Defense', 'Education', 'Healthcare', \n 'Immigration', 'Innovation', 'Environment', 'Veterans', 'Economy']\n\n# Plot the sample speeches with labels\nhyp.plot(sample_speeches, labels=labels)" + ] + } + ], + "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# Plotting State of the Union Addresses with Text Analysis\n\nThis example demonstrates how to plot text data using hypertools. We create\nsample State of the Union address excerpts covering different political themes\nand visualize them in a reduced dimensional space. By default, hypertools \ntransforms the text data using a topic model to capture semantic relationships \nbetween different speech segments.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# load hypertools\nimport hypertools as hyp\n\n# load the data\n# Note: 'sotus' loads a text processing model, not the actual SOTU speeches\n# We'll create sample text data to demonstrate text plotting capabilities\nprint(\"Creating sample State of the Union demonstration...\")\n\n# Sample State of the Union excerpts for demonstration\nsample_speeches = [\n \"Tonight I can report to the nation that America is stronger, America is more secure, and America is respected again. After years of decline, our economy is growing again.\",\n \"We gather tonight knowing that this generation of Americans has been tested by crisis and proven worthy of our founding principles. The state of our union is strong.\",\n \"As we work together to advance America's interests, we must also recognize the threats we face. We will rebuild our military and defend our nation.\",\n \"Education is the great equalizer in America. We must ensure every child has access to quality education regardless of their zip code.\",\n \"Healthcare should be affordable and accessible to all Americans. We will work to reduce costs while maintaining quality care.\",\n \"We must secure our borders and have an immigration system that works for America and reflects our values.\",\n \"Innovation and technology will drive America forward in the 21st century. We must invest in research and development.\",\n \"Climate change poses real challenges, and we will address them with American innovation and determination.\",\n \"Our military is the finest in the world, and we will ensure our veterans receive the care they have earned.\",\n \"The economy is strong, unemployment is low, and American families are prospering like never before.\"\n]\n\n# Add labels for the different themes\nlabels = ['Security', 'Unity', 'Defense', 'Education', 'Healthcare', \n 'Immigration', 'Innovation', 'Environment', 'Veterans', 'Economy']\n\n# Plot the sample speeches with labels\nhyp.plot(sample_speeches, labels=labels)" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_sotus.rst b/docs/auto_examples/plot_sotus.rst index 168ad4a0..0e11bbf5 100644 --- a/docs/auto_examples/plot_sotus.rst +++ b/docs/auto_examples/plot_sotus.rst @@ -43,17 +43,16 @@ between different speech segments. .. code-block:: none Creating sample State of the Union demonstration... - /Users/jmanning/miniconda3/lib/python3.12/site-packages/sklearn/base.py:376: InconsistentVersionWarning: Trying to unpickle estimator CountVectorizer from version 1.0.2 when using version 1.5.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: + /Users/jmanning/hypertools/.venv/lib/python3.12/site-packages/sklearn/base.py:463: InconsistentVersionWarning: Trying to unpickle estimator CountVectorizer from version 1.0.2 when using version 1.8.0. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations warnings.warn( - /Users/jmanning/miniconda3/lib/python3.12/site-packages/sklearn/base.py:376: InconsistentVersionWarning: Trying to unpickle estimator LatentDirichletAllocation from version 1.0.2 when using version 1.5.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: + /Users/jmanning/hypertools/.venv/lib/python3.12/site-packages/sklearn/base.py:463: InconsistentVersionWarning: Trying to unpickle estimator LatentDirichletAllocation from version 1.0.2 when using version 1.8.0. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations warnings.warn( - /Users/jmanning/miniconda3/lib/python3.12/site-packages/sklearn/base.py:376: InconsistentVersionWarning: Trying to unpickle estimator Pipeline from version 1.0.2 when using version 1.5.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: + /Users/jmanning/hypertools/.venv/lib/python3.12/site-packages/sklearn/base.py:463: InconsistentVersionWarning: Trying to unpickle estimator Pipeline from version 1.0.2 when using version 1.8.0. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations warnings.warn( - @@ -99,9 +98,7 @@ between different speech segments. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 3.339 seconds) - -**Estimated memory usage:** 403 MB + **Total running time of the script:** (0 minutes 0.117 seconds) .. _sphx_glr_download_auto_examples_plot_sotus.py: diff --git a/docs/auto_examples/plot_sotus.zip b/docs/auto_examples/plot_sotus.zip index 49577a4c..1bb59ae0 100644 Binary files a/docs/auto_examples/plot_sotus.zip and b/docs/auto_examples/plot_sotus.zip differ diff --git a/docs/auto_examples/plot_surface.codeobj.json b/docs/auto_examples/plot_surface.codeobj.json new file mode 100644 index 00000000..c4724128 --- /dev/null +++ b/docs/auto_examples/plot_surface.codeobj.json @@ -0,0 +1,107 @@ +{ + "blob_a": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "blob_b": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "custom_surface": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "hyp.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "hypertools", + "module_short": "hypertools", + "name": "plot" + } + ], + "np.random.default_rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_2_1", + "module_short": "_cython_3_2_1", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "default_rng" + } + ], + "rng": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator" + } + ], + "rng.standard_normal": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random._generator", + "module_short": "numpy.random", + "name": "Generator.standard_normal" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy.random", + "module_short": "numpy.random", + "name": "Generator.standard_normal" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "Generator.standard_normal" + } + ] +} \ No newline at end of file diff --git a/docs/auto_examples/plot_surface.ipynb b/docs/auto_examples/plot_surface.ipynb new file mode 100644 index 00000000..1b722c83 --- /dev/null +++ b/docs/auto_examples/plot_surface.ipynb @@ -0,0 +1,72 @@ +{ + "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# Surfaces around point clouds\n\nThe `surface` kwarg overlays a smooth, lit surface over each dataset's\nconvex hull: a filled outline for 2D data, or a shaded, Taubin-smoothed\n3D \"blob\" for 3D data (GH #109). Pass `surface=True` for sensible\ndefaults, or a dict to customize the alpha, color, lighting, and amount\nof smoothing.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nimport numpy as np\n\nimport hypertools as hyp\n\nrng = np.random.default_rng(0)\n\n# two blobby 3D point clouds\nblob_a = rng.standard_normal((300, 3)) * [1.0, 0.6, 0.8]\nblob_b = rng.standard_normal((300, 3)) * [0.7, 1.0, 0.6] + [3.5, 0, 0]\n\n# default surfaces: hyp.plot infers sensible alpha/lighting/smoothing\nhyp.plot([blob_a, blob_b], '.', surface=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The dict API gives per-call control over the surface's look: `alpha`\n(transparency), `color` (overrides the dataset's own drawn color),\n`lighting` (a dict of Blinn-Phong shading terms), and `smoothing`\n(rounds of Taubin mesh smoothing -- higher looks glossier but is\nslower to compute).\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "custom_surface = {\n 'alpha': 0.5,\n 'color': '#2E86AB',\n 'lighting': {'ambient': 0.6, 'diffuse': 0.5, 'specular': 0.4},\n 'smoothing': 2,\n}\n\nhyp.plot([blob_a, blob_b], '.', surface=custom_surface)" + ] + } + ], + "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 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_surface.py b/docs/auto_examples/plot_surface.py new file mode 100644 index 00000000..4800ea6f --- /dev/null +++ b/docs/auto_examples/plot_surface.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +""" +============================= +Surfaces around point clouds +============================= + +The `surface` kwarg overlays a smooth, lit surface over each dataset's +convex hull: a filled outline for 2D data, or a shaded, Taubin-smoothed +3D "blob" for 3D data (GH #109). Pass `surface=True` for sensible +defaults, or a dict to customize the alpha, color, lighting, and amount +of smoothing. +""" + +# Code source: Contextual Dynamics Laboratory +# License: MIT + +import numpy as np + +import hypertools as hyp + +rng = np.random.default_rng(0) + +# two blobby 3D point clouds +blob_a = rng.standard_normal((300, 3)) * [1.0, 0.6, 0.8] +blob_b = rng.standard_normal((300, 3)) * [0.7, 1.0, 0.6] + [3.5, 0, 0] + +# default surfaces: hyp.plot infers sensible alpha/lighting/smoothing +hyp.plot([blob_a, blob_b], '.', surface=True) + +############################################################################### +# The dict API gives per-call control over the surface's look: `alpha` +# (transparency), `color` (overrides the dataset's own drawn color), +# `lighting` (a dict of Blinn-Phong shading terms), and `smoothing` +# (rounds of Taubin mesh smoothing -- higher looks glossier but is +# slower to compute). + +custom_surface = { + 'alpha': 0.5, + 'color': '#2E86AB', + 'lighting': {'ambient': 0.6, 'diffuse': 0.5, 'specular': 0.4}, + 'smoothing': 2, +} + +hyp.plot([blob_a, blob_b], '.', surface=custom_surface) diff --git a/docs/auto_examples/plot_surface.py.md5 b/docs/auto_examples/plot_surface.py.md5 new file mode 100644 index 00000000..67fb1eb7 --- /dev/null +++ b/docs/auto_examples/plot_surface.py.md5 @@ -0,0 +1 @@ +58c7d31745e01ee65f906aee618933d8 \ No newline at end of file diff --git a/docs/auto_examples/plot_surface.rst b/docs/auto_examples/plot_surface.rst new file mode 100644 index 00000000..d4b1b0da --- /dev/null +++ b/docs/auto_examples/plot_surface.rst @@ -0,0 +1,126 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/plot_surface.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_plot_surface.py: + + +============================= +Surfaces around point clouds +============================= + +The `surface` kwarg overlays a smooth, lit surface over each dataset's +convex hull: a filled outline for 2D data, or a shaded, Taubin-smoothed +3D "blob" for 3D data (GH #109). Pass `surface=True` for sensible +defaults, or a dict to customize the alpha, color, lighting, and amount +of smoothing. + +.. GENERATED FROM PYTHON SOURCE LINES 13-30 + +.. code-block:: Python + + + # Code source: Contextual Dynamics Laboratory + # License: MIT + + import numpy as np + + import hypertools as hyp + + rng = np.random.default_rng(0) + + # two blobby 3D point clouds + blob_a = rng.standard_normal((300, 3)) * [1.0, 0.6, 0.8] + blob_b = rng.standard_normal((300, 3)) * [0.7, 1.0, 0.6] + [3.5, 0, 0] + + # default surfaces: hyp.plot infers sensible alpha/lighting/smoothing + hyp.plot([blob_a, blob_b], '.', surface=True) + + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_surface_001.png + :alt: plot surface + :srcset: /auto_examples/images/sphx_glr_plot_surface_001.png + :class: sphx-glr-single-img + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 31-36 + +The dict API gives per-call control over the surface's look: `alpha` +(transparency), `color` (overrides the dataset's own drawn color), +`lighting` (a dict of Blinn-Phong shading terms), and `smoothing` +(rounds of Taubin mesh smoothing -- higher looks glossier but is +slower to compute). + +.. GENERATED FROM PYTHON SOURCE LINES 36-45 + +.. code-block:: Python + + + custom_surface = { + 'alpha': 0.5, + 'color': '#2E86AB', + 'lighting': {'ambient': 0.6, 'diffuse': 0.5, 'specular': 0.4}, + 'smoothing': 2, + } + + hyp.plot([blob_a, blob_b], '.', surface=custom_surface) + + + +.. image-sg:: /auto_examples/images/sphx_glr_plot_surface_002.png + :alt: plot surface + :srcset: /auto_examples/images/sphx_glr_plot_surface_002.png + :class: sphx-glr-single-img + + + + + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 0.296 seconds) + + +.. _sphx_glr_download_auto_examples_plot_surface.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: plot_surface.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: plot_surface.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: plot_surface.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/auto_examples/plot_surface.zip b/docs/auto_examples/plot_surface.zip new file mode 100644 index 00000000..dbf3de5c Binary files /dev/null and b/docs/auto_examples/plot_surface.zip differ diff --git a/docs/auto_examples/plot_text.ipynb b/docs/auto_examples/plot_text.ipynb index f4ffccd4..923c5fe5 100644 --- a/docs/auto_examples/plot_text.ipynb +++ b/docs/auto_examples/plot_text.ipynb @@ -1,54 +1,54 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "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\"" - ] + "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# Plotting text\n\nTo plot text, simply pass the text data to the plot function. By default, the\ntext samples will be transformed into a vector of word counts and then modeled\nusing Latent Dirichlet Allocation (# of topics = 100) using a model fit to a\nlarge sample of wikipedia pages. If you specify semantic=None, the word\ncount vectors will be plotted. To convert the text t0 a matrix (or list of\nmatrices), we also expose the format_data function.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Code source: Andrew Heusser\n# License: MIT\n\n# load hypertools\nimport hypertools as hyp\n\n# load the data\ndata = [['i like cats alot', 'cats r pretty cool', 'cats are better than dogs'],\n ['dogs rule the haus', 'dogs are my jam', 'dogs are a mans best friend'],\n 'i haz a cheezeburger?']\n\n# plot it\nhyp.plot(data, 'o')\n\n# convert text to matrix without plotting\n# mtx = hyp.tools.format_data(data, vectorizer='TfidfVectorizer', semantic='NMF')" + ] + } + ], + "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# Plotting text\n\nTo plot text, simply pass the text data to the plot function. By default, the\ntext samples will be transformed into a vector of word counts and then modeled\nusing Latent Dirichlet Allocation (# of topics = 100) using a model fit to a\nlarge sample of wikipedia pages. If you specify semantic=None, the word\ncount vectors will be plotted. To convert the text t0 a matrix (or list of\nmatrices), we also expose the format_data function.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Code source: Andrew Heusser\n# License: MIT\n\n# load hypertools\nimport hypertools as hyp\n\n# load the data\ndata = [['i like cats alot', 'cats r pretty cool', 'cats are better than dogs'],\n ['dogs rule the haus', 'dogs are my jam', 'dogs are a mans best friend'],\n 'i haz a cheezeburger?']\n\n# plot it\nhyp.plot(data, 'o')\n\n# convert text to matrix without plotting\n# mtx = hyp.tools.format_data(data, vectorizer='TfidfVectorizer', semantic='NMF')" - ] - } - ], - "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.4" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/auto_examples/plot_text.rst b/docs/auto_examples/plot_text.rst index 01b3ea8c..0bc82bdf 100644 --- a/docs/auto_examples/plot_text.rst +++ b/docs/auto_examples/plot_text.rst @@ -43,17 +43,16 @@ matrices), we also expose the format_data function. .. code-block:: none - /Users/jmanning/miniconda3/lib/python3.12/site-packages/sklearn/base.py:376: InconsistentVersionWarning: Trying to unpickle estimator CountVectorizer from version 1.0.2 when using version 1.5.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: + /Users/jmanning/hypertools/.venv/lib/python3.12/site-packages/sklearn/base.py:463: InconsistentVersionWarning: Trying to unpickle estimator CountVectorizer from version 1.0.2 when using version 1.8.0. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations warnings.warn( - /Users/jmanning/miniconda3/lib/python3.12/site-packages/sklearn/base.py:376: InconsistentVersionWarning: Trying to unpickle estimator LatentDirichletAllocation from version 1.0.2 when using version 1.5.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: + /Users/jmanning/hypertools/.venv/lib/python3.12/site-packages/sklearn/base.py:463: InconsistentVersionWarning: Trying to unpickle estimator LatentDirichletAllocation from version 1.0.2 when using version 1.8.0. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations warnings.warn( - /Users/jmanning/miniconda3/lib/python3.12/site-packages/sklearn/base.py:376: InconsistentVersionWarning: Trying to unpickle estimator Pipeline from version 1.0.2 when using version 1.5.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: + /Users/jmanning/hypertools/.venv/lib/python3.12/site-packages/sklearn/base.py:463: InconsistentVersionWarning: Trying to unpickle estimator Pipeline from version 1.0.2 when using version 1.8.0. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to: https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations warnings.warn( - @@ -84,7 +83,7 @@ matrices), we also expose the format_data function. .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.053 seconds) + **Total running time of the script:** (0 minutes 0.049 seconds) .. _sphx_glr_download_auto_examples_plot_text.py: diff --git a/docs/auto_examples/plot_text.zip b/docs/auto_examples/plot_text.zip index 9abdf47c..14761e57 100644 Binary files a/docs/auto_examples/plot_text.zip and b/docs/auto_examples/plot_text.zip differ diff --git a/docs/auto_examples/precog.codeobj.json b/docs/auto_examples/precog.codeobj.json index 1503c46f..dc560397 100644 --- a/docs/auto_examples/precog.codeobj.json +++ b/docs/auto_examples/precog.codeobj.json @@ -15,71 +15,48 @@ "name": "FuncAnimation" } ], - "ani_geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "ani_geo.line_ani": [ + "fig": [ { "is_class": false, "is_explicit": false, - "module": "matplotlib.animation", - "module_short": "matplotlib.animation", - "name": "FuncAnimation" + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" }, { "is_class": false, "is_explicit": false, "module": "matplotlib", "module_short": "matplotlib", - "name": "FuncAnimation" + "name": "Figure" } ], - "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.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -92,7 +69,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ] } \ No newline at end of file diff --git a/docs/auto_examples/precog.ipynb b/docs/auto_examples/precog.ipynb index ba30ae1b..77b49dd7 100644 --- a/docs/auto_examples/precog.ipynb +++ b/docs/auto_examples/precog.ipynb @@ -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# Precognition\n\nThe future trajectory of an animated plot can be visualized with the precog\nargument. This displays a low opacity version of the trace ahead of the\ncurrent points being plotted. This can be used in conjunction with the\nchemtrails argument to plot a low-opacity trace of the entire timeseries.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_precog_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ndata = hyp.load('weights_avg')\n\n# plot\nfig, ani = hyp.plot(data, animate=True, precog=True)" + ] + } + ], + "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# Precognition\n\nThe future trajectory of an animated plot can be visualized with the precog\nargument. This displays a low opacity version of the trace ahead of the\ncurrent points being plotted. This can be used in conjunction with the\nchemtrails argument to plot a low-opacity trace of the entire timeseries.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_precog_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ngeo = hyp.load('weights_avg')\n\n# plot\nani_geo = geo.plot(animate=True, precog=True)\nani = ani_geo.line_ani # the underlying matplotlib FuncAnimation" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/precog.py b/docs/auto_examples/precog.py index 3048d924..280dc47b 100644 --- a/docs/auto_examples/precog.py +++ b/docs/auto_examples/precog.py @@ -20,8 +20,7 @@ import numpy as np # load example data -geo = hyp.load('weights_avg') +data = hyp.load('weights_avg') # plot -ani_geo = geo.plot(animate=True, precog=True) -ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation +fig, ani = hyp.plot(data, animate=True, precog=True) diff --git a/docs/auto_examples/precog.py.md5 b/docs/auto_examples/precog.py.md5 index 34887f88..42a8f677 100644 --- a/docs/auto_examples/precog.py.md5 +++ b/docs/auto_examples/precog.py.md5 @@ -1 +1 @@ -437472c6ce39e600a822d6665feffa0b \ No newline at end of file +9f131b378212097cc81e66341443ef8e \ No newline at end of file diff --git a/docs/auto_examples/precog.rst b/docs/auto_examples/precog.rst index d6fae6fc..aee6c7d7 100644 --- a/docs/auto_examples/precog.rst +++ b/docs/auto_examples/precog.rst @@ -27,7 +27,7 @@ argument. This displays a low opacity version of the trace ahead of the current points being plotted. This can be used in conjunction with the chemtrails argument to plot a low-opacity trace of the entire timeseries. -.. GENERATED FROM PYTHON SOURCE LINES 12-28 +.. GENERATED FROM PYTHON SOURCE LINES 12-27 @@ -55,16 +55,15 @@ chemtrails argument to plot a low-opacity trace of the entire timeseries. import numpy as np # load example data - geo = hyp.load('weights_avg') + data = hyp.load('weights_avg') # plot - ani_geo = geo.plot(animate=True, precog=True) - ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation + fig, ani = hyp.plot(data, animate=True, precog=True) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 7.746 seconds) + **Total running time of the script:** (0 minutes 6.255 seconds) .. _sphx_glr_download_auto_examples_precog.py: diff --git a/docs/auto_examples/precog.zip b/docs/auto_examples/precog.zip index cc6f71f4..8c6216b0 100644 Binary files a/docs/auto_examples/precog.zip and b/docs/auto_examples/precog.zip differ diff --git a/docs/auto_examples/save_image.codeobj.json b/docs/auto_examples/save_image.codeobj.json index 3e223b4f..4d804f74 100644 --- a/docs/auto_examples/save_image.codeobj.json +++ b/docs/auto_examples/save_image.codeobj.json @@ -1,37 +1,30 @@ { - "geo": [ + "data": [ { "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" + "module": "builtins", + "module_short": "builtins", + "name": "list" } ], - "geo.plot": [ + "hyp.load": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry.plot" + "module": "builtins", + "module_short": "builtins", + "name": "function" }, { "is_class": false, "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "DataGeometry.plot" + "name": "load" } ], - "hyp.load": [ + "hyp.plot": [ { "is_class": false, "is_explicit": false, @@ -44,7 +37,7 @@ "is_explicit": false, "module": "hypertools", "module_short": "hypertools", - "name": "load" + "name": "plot" } ], "os.path.join": [ diff --git a/docs/auto_examples/save_image.ipynb b/docs/auto_examples/save_image.ipynb index 03cbbf8d..baafc17d 100644 --- a/docs/auto_examples/save_image.ipynb +++ b/docs/auto_examples/save_image.ipynb @@ -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# Saving a plot\n\nTo save a plot, simply use the `save_path` kwarg, and specify where you want\nthe image to be saved, including the file extension (e.g. pdf)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_save_image_thumb.png'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ndata = hyp.load('weights_sample')\n\n# plot\nimport os, tempfile\nsave_path = os.path.join(tempfile.mkdtemp(), 'test-image.pdf')\nhyp.plot(data, fmt='o', save_path=save_path)" + ] + } + ], + "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# Saving a plot\n\nTo save a plot, simply use the `save_path` kwarg, and specify where you want\nthe image to be saved, including the file extension (e.g. pdf)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_save_image_thumb.png'\n\n# Code source: Andrew Heusser\n# License: MIT\n\n# import\nimport hypertools as hyp\nimport numpy as np\n\n# load example data\ngeo = hyp.load('weights_sample')\n\n# plot\nimport os, tempfile\nsave_path = os.path.join(tempfile.mkdtemp(), 'test-image.pdf')\ngeo.plot(fmt='o', save_path=save_path)" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/save_image.py b/docs/auto_examples/save_image.py index fe9106e8..29b01808 100644 --- a/docs/auto_examples/save_image.py +++ b/docs/auto_examples/save_image.py @@ -18,9 +18,9 @@ import numpy as np # load example data -geo = hyp.load('weights_sample') +data = hyp.load('weights_sample') # plot import os, tempfile save_path = os.path.join(tempfile.mkdtemp(), 'test-image.pdf') -geo.plot(fmt='o', save_path=save_path) +hyp.plot(data, fmt='o', save_path=save_path) diff --git a/docs/auto_examples/save_image.py.md5 b/docs/auto_examples/save_image.py.md5 index 2151f40e..82f17be5 100644 --- a/docs/auto_examples/save_image.py.md5 +++ b/docs/auto_examples/save_image.py.md5 @@ -1 +1 @@ -3e4bc1fbc5f7bf65c0405385662502fe \ No newline at end of file +271c8fff8d3bae315cec26ff6c401dfd \ No newline at end of file diff --git a/docs/auto_examples/save_image.rst b/docs/auto_examples/save_image.rst index 0cde03b9..98aa627b 100644 --- a/docs/auto_examples/save_image.rst +++ b/docs/auto_examples/save_image.rst @@ -51,17 +51,17 @@ the image to be saved, including the file extension (e.g. pdf) import numpy as np # load example data - geo = hyp.load('weights_sample') + data = hyp.load('weights_sample') # plot import os, tempfile save_path = os.path.join(tempfile.mkdtemp(), 'test-image.pdf') - geo.plot(fmt='o', save_path=save_path) + hyp.plot(data, fmt='o', save_path=save_path) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 0.096 seconds) + **Total running time of the script:** (0 minutes 0.112 seconds) .. _sphx_glr_download_auto_examples_save_image.py: diff --git a/docs/auto_examples/save_image.zip b/docs/auto_examples/save_image.zip index 6cf18fd4..86a8cd3d 100644 Binary files a/docs/auto_examples/save_image.zip and b/docs/auto_examples/save_image.zip differ diff --git a/docs/auto_examples/save_movie.codeobj.json b/docs/auto_examples/save_movie.codeobj.json index 4b0a40e9..5fb8066c 100644 --- a/docs/auto_examples/save_movie.codeobj.json +++ b/docs/auto_examples/save_movie.codeobj.json @@ -15,38 +15,6 @@ "name": "FuncAnimation" } ], - "ani_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" - } - ], - "ani_geo.line_ani": [ - { - "is_class": false, - "is_explicit": false, - "module": "matplotlib.animation", - "module_short": "matplotlib.animation", - "name": "FuncAnimation" - }, - { - "is_class": false, - "is_explicit": false, - "module": "matplotlib", - "module_short": "matplotlib", - "name": "FuncAnimation" - } - ], "data": [ { "is_class": false, @@ -56,29 +24,20 @@ "name": "list" } ], - "geo": [ + "fig": [ { "is_class": false, "is_explicit": false, - "module": "hypertools.datageometry", - "module_short": "hypertools", - "name": "DataGeometry" + "module": "matplotlib.figure", + "module_short": "matplotlib.figure", + "name": "Figure" }, { "is_class": false, "is_explicit": false, - "module": "hypertools", - "module_short": "hypertools", - "name": "DataGeometry" - } - ], - "geo.data": [ - { - "is_class": false, - "is_explicit": false, - "module": "builtins", - "module_short": "builtins", - "name": "list" + "module": "matplotlib", + "module_short": "matplotlib", + "name": "Figure" } ], "group1": [ diff --git a/docs/auto_examples/save_movie.ipynb b/docs/auto_examples/save_movie.ipynb index 1296432a..8d3f13ef 100644 --- a/docs/auto_examples/save_movie.ipynb +++ b/docs/auto_examples/save_movie.ipynb @@ -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# Saving an animation\n\nTo save an animation, simply add the `save_path` kwarg and specify the path\nwhere you want to save the movie, including the extension. NOTE: this\ndepends on having ffmpeg installed on your computer.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_save_movie_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\nimport hypertools as hyp\nimport numpy as np\n\ndata = hyp.load('weights', align='hyper')\n\ngroup1 = np.mean(data[:17], 0)\ngroup2 = np.mean(data[18:], 0)\n\nimport os, tempfile\nsave_path = os.path.join(tempfile.mkdtemp(), 'animation.mp4')\nfig, ani = hyp.plot([group1, group2], animate=True, save_path=save_path)" + ] + } + ], + "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# Saving an animation\n\nTo save an animation, simply add the `save_path` kwarg and specify the path\nwhere you want to save the movie, including the extension. NOTE: this\ndepends on having ffmpeg installed on your computer.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# sphinx_gallery_thumbnail_path = '_static/thumbnails/sphx_glr_save_movie_thumb.gif'\n\n# Code source: Andrew Heusser\n# License: MIT\n\nimport hypertools as hyp\nimport numpy as np\n\ngeo = hyp.load('weights', align='hyper')\n\n# Extract data from the geo object\ndata = geo.data\n\ngroup1 = np.mean(data[:17], 0)\ngroup2 = np.mean(data[18:], 0)\n\nimport os, tempfile\nsave_path = os.path.join(tempfile.mkdtemp(), 'animation.mp4')\nani_geo = hyp.plot([group1, group2], animate=True, save_path=save_path)\nani = ani_geo.line_ani # the underlying matplotlib FuncAnimation" - ] - } - ], - "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 +} \ No newline at end of file diff --git a/docs/auto_examples/save_movie.py b/docs/auto_examples/save_movie.py index 083d0799..324a8fb9 100644 --- a/docs/auto_examples/save_movie.py +++ b/docs/auto_examples/save_movie.py @@ -17,15 +17,11 @@ import hypertools as hyp import numpy as np -geo = hyp.load('weights', align='hyper') - -# Extract data from the geo object -data = geo.data +data = hyp.load('weights', align='hyper') group1 = np.mean(data[:17], 0) group2 = np.mean(data[18:], 0) import os, tempfile save_path = os.path.join(tempfile.mkdtemp(), 'animation.mp4') -ani_geo = hyp.plot([group1, group2], animate=True, save_path=save_path) -ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation +fig, ani = hyp.plot([group1, group2], animate=True, save_path=save_path) diff --git a/docs/auto_examples/save_movie.py.md5 b/docs/auto_examples/save_movie.py.md5 index 19a75b1c..cbf66a06 100644 --- a/docs/auto_examples/save_movie.py.md5 +++ b/docs/auto_examples/save_movie.py.md5 @@ -1 +1 @@ -f91af0a9941f6e2da3b5fc37d8e3581b \ No newline at end of file +eb7ee92c4e72e7951b5e6e4d101789fe \ No newline at end of file diff --git a/docs/auto_examples/save_movie.rst b/docs/auto_examples/save_movie.rst index 66dc538a..0cc2462b 100644 --- a/docs/auto_examples/save_movie.rst +++ b/docs/auto_examples/save_movie.rst @@ -26,27 +26,15 @@ To save an animation, simply add the `save_path` kwarg and specify the path where you want to save the movie, including the extension. NOTE: this depends on having ffmpeg installed on your computer. -.. GENERATED FROM PYTHON SOURCE LINES 11-32 +.. GENERATED FROM PYTHON SOURCE LINES 11-28 -.. rst-class:: sphx-glr-horizontal - - - * - - .. image-sg:: /auto_examples/images/sphx_glr_save_movie_001.png - :alt: save movie - :srcset: /auto_examples/images/sphx_glr_save_movie_001.png - :class: sphx-glr-multi-img - - * - - .. video:: /auto_examples/images/sphx_glr_save_movie_002.mp4 - :class: sphx-glr-multi-img - :height: 480 - :width: 640 - :autoplay: +.. video:: /auto_examples/images/sphx_glr_save_movie_001.mp4 + :class: sphx-glr-single-img + :height: 480 + :width: 640 + :autoplay: @@ -64,23 +52,19 @@ depends on having ffmpeg installed on your computer. import hypertools as hyp import numpy as np - geo = hyp.load('weights', align='hyper') - - # Extract data from the geo object - data = geo.data + data = hyp.load('weights', align='hyper') group1 = np.mean(data[:17], 0) group2 = np.mean(data[18:], 0) import os, tempfile save_path = os.path.join(tempfile.mkdtemp(), 'animation.mp4') - ani_geo = hyp.plot([group1, group2], animate=True, save_path=save_path) - ani = ani_geo.line_ani # the underlying matplotlib FuncAnimation + fig, ani = hyp.plot([group1, group2], animate=True, save_path=save_path) .. rst-class:: sphx-glr-timing - **Total running time of the script:** (0 minutes 12.173 seconds) + **Total running time of the script:** (0 minutes 9.680 seconds) .. _sphx_glr_download_auto_examples_save_movie.py: diff --git a/docs/auto_examples/save_movie.zip b/docs/auto_examples/save_movie.zip index 466c3d98..957ee9ed 100644 Binary files a/docs/auto_examples/save_movie.zip and b/docs/auto_examples/save_movie.zip differ diff --git a/docs/auto_examples/sg_execution_times.rst b/docs/auto_examples/sg_execution_times.rst index 301467a3..d2730920 100644 --- a/docs/auto_examples/sg_execution_times.rst +++ b/docs/auto_examples/sg_execution_times.rst @@ -6,7 +6,7 @@ Computation times ================= -**00:01.059** total execution time for 39 files **from auto_examples**: +**02:48.154** total execution time for 48 files **from auto_examples**: .. container:: @@ -32,19 +32,31 @@ Computation times * - Example - Time - Mem (MB) - * - :ref:`sphx_glr_auto_examples_plot_datasaurus.py` (``plot_datasaurus.py``) - - 00:00.835 + * - :ref:`sphx_glr_auto_examples_animate_surface_morph.py` (``animate_surface_morph.py``) + - 01:57.221 - 0.0 - * - :ref:`sphx_glr_auto_examples_plot_shapes_zoo.py` (``plot_shapes_zoo.py``) - - 00:00.224 + * - :ref:`sphx_glr_auto_examples_animate.py` (``animate.py``) + - 00:12.906 - 0.0 - * - :ref:`sphx_glr_auto_examples_analyze.py` (``analyze.py``) - - 00:00.000 + * - :ref:`sphx_glr_auto_examples_save_movie.py` (``save_movie.py``) + - 00:09.680 - 0.0 - * - :ref:`sphx_glr_auto_examples_animate.py` (``animate.py``) - - 00:00.000 + * - :ref:`sphx_glr_auto_examples_animate_trails_mix.py` (``animate_trails_mix.py``) + - 00:06.351 + - 0.0 + * - :ref:`sphx_glr_auto_examples_chemtrails.py` (``chemtrails.py``) + - 00:06.295 + - 0.0 + * - :ref:`sphx_glr_auto_examples_precog.py` (``precog.py``) + - 00:06.255 - 0.0 * - :ref:`sphx_glr_auto_examples_animate_MDS.py` (``animate_MDS.py``) + - 00:05.847 + - 0.0 + * - :ref:`sphx_glr_auto_examples_plot_shape_morph.py` (``plot_shape_morph.py``) + - 00:03.598 + - 0.0 + * - :ref:`sphx_glr_auto_examples_analyze.py` (``analyze.py``) - 00:00.000 - 0.0 * - :ref:`sphx_glr_auto_examples_animate_plotly.py` (``animate_plotly.py``) @@ -53,9 +65,6 @@ Computation times * - :ref:`sphx_glr_auto_examples_animate_spin.py` (``animate_spin.py``) - 00:00.000 - 0.0 - * - :ref:`sphx_glr_auto_examples_chemtrails.py` (``chemtrails.py``) - - 00:00.000 - - 0.0 * - :ref:`sphx_glr_auto_examples_explore.py` (``explore.py``) - 00:00.000 - 0.0 @@ -89,12 +98,21 @@ Computation times * - :ref:`sphx_glr_auto_examples_plot_clusters3.py` (``plot_clusters3.py``) - 00:00.000 - 0.0 + * - :ref:`sphx_glr_auto_examples_plot_colorbar.py` (``plot_colorbar.py``) + - 00:00.000 + - 0.0 * - :ref:`sphx_glr_auto_examples_plot_corpus.py` (``plot_corpus.py``) - 00:00.000 - 0.0 * - :ref:`sphx_glr_auto_examples_plot_dataframe.py` (``plot_dataframe.py``) - 00:00.000 - 0.0 + * - :ref:`sphx_glr_auto_examples_plot_datasaurus.py` (``plot_datasaurus.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_plot_density.py` (``plot_density.py``) + - 00:00.000 + - 0.0 * - :ref:`sphx_glr_auto_examples_plot_describe.py` (``plot_describe.py``) - 00:00.000 - 0.0 @@ -107,6 +125,9 @@ Computation times * - :ref:`sphx_glr_auto_examples_plot_hue.py` (``plot_hue.py``) - 00:00.000 - 0.0 + * - :ref:`sphx_glr_auto_examples_plot_impute.py` (``plot_impute.py``) + - 00:00.000 + - 0.0 * - :ref:`sphx_glr_auto_examples_plot_interactive_backend.py` (``plot_interactive_backend.py``) - 00:00.000 - 0.0 @@ -125,27 +146,33 @@ Computation times * - :ref:`sphx_glr_auto_examples_plot_multicolored_lines.py` (``plot_multicolored_lines.py``) - 00:00.000 - 0.0 + * - :ref:`sphx_glr_auto_examples_plot_multiindex.py` (``plot_multiindex.py``) + - 00:00.000 + - 0.0 * - :ref:`sphx_glr_auto_examples_plot_nested_lists.py` (``plot_nested_lists.py``) - 00:00.000 - 0.0 * - :ref:`sphx_glr_auto_examples_plot_normalize.py` (``plot_normalize.py``) - 00:00.000 - 0.0 + * - :ref:`sphx_glr_auto_examples_plot_predict.py` (``plot_predict.py``) + - 00:00.000 + - 0.0 * - :ref:`sphx_glr_auto_examples_plot_procrustes.py` (``plot_procrustes.py``) - 00:00.000 - 0.0 - * - :ref:`sphx_glr_auto_examples_plot_sotus.py` (``plot_sotus.py``) + * - :ref:`sphx_glr_auto_examples_plot_shapes_zoo.py` (``plot_shapes_zoo.py``) - 00:00.000 - 0.0 - * - :ref:`sphx_glr_auto_examples_plot_text.py` (``plot_text.py``) + * - :ref:`sphx_glr_auto_examples_plot_sotus.py` (``plot_sotus.py``) - 00:00.000 - 0.0 - * - :ref:`sphx_glr_auto_examples_precog.py` (``precog.py``) + * - :ref:`sphx_glr_auto_examples_plot_surface.py` (``plot_surface.py``) - 00:00.000 - 0.0 - * - :ref:`sphx_glr_auto_examples_save_image.py` (``save_image.py``) + * - :ref:`sphx_glr_auto_examples_plot_text.py` (``plot_text.py``) - 00:00.000 - 0.0 - * - :ref:`sphx_glr_auto_examples_save_movie.py` (``save_movie.py``) + * - :ref:`sphx_glr_auto_examples_save_image.py` (``save_image.py``) - 00:00.000 - 0.0 diff --git a/docs/auto_examples/spin.gif b/docs/auto_examples/spin.gif index 6702e7f7..50e33570 100644 Binary files a/docs/auto_examples/spin.gif and b/docs/auto_examples/spin.gif differ diff --git a/docs/conf.py b/docs/conf.py index b4b08aaf..734eee1f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -36,7 +36,7 @@ def plotly_sg_scraper(*args, **kwargs): def _install_notebook_cell(): """First cell for every gallery notebook: install hypertools so the notebook runs standalone in Colab. Branch-aware -- installs the current - branch from GitHub for previews (e.g. dev-2.0), or the released package + branch from GitHub for previews (e.g. dev-1.0), or the released package on master. Kept in sync with scripts/add_colab_install_cell.py, which injects the same line into the hand-authored tutorial notebooks.""" import subprocess diff --git a/docs/doc_requirements.txt b/docs/doc_requirements.txt index 519ffd35..c7b0374f 100644 --- a/docs/doc_requirements.txt +++ b/docs/doc_requirements.txt @@ -22,3 +22,11 @@ ipympl>=0.9.3 # Optional dependencies for examples hdbscan>=0.8.11 memory_profiler +# hyp.predict/[predict] models used by gallery examples (plot_predict, plot_impute) +pykalman>=0.11 +statsmodels>=0.14 +skaters>=0.11 +# plot(..., density=True) 3-D iso-surfaces ([density3d] extra); gallery +# examples build with it installed so the docs show the iso-surface path +# rather than the scatter-fog fallback +scikit-image>=0.22.0 diff --git a/docs/hypertools.DataGeometry.rst b/docs/hypertools.DataGeometry.rst deleted file mode 100644 index ae60ba4d..00000000 --- a/docs/hypertools.DataGeometry.rst +++ /dev/null @@ -1,27 +0,0 @@ -hypertools.DataGeometry -======================= - -.. currentmodule:: hypertools - -.. autoclass:: DataGeometry - - - .. automethod:: __init__ - - - .. rubric:: Methods - - .. autosummary:: - - ~DataGeometry.__init__ - ~DataGeometry.get_data - ~DataGeometry.get_formatted_data - ~DataGeometry.plot - ~DataGeometry.save - ~DataGeometry.transform - - - - - - \ No newline at end of file diff --git a/docs/hypertools.align.procrustes.rst b/docs/hypertools.align.procrustes.rst new file mode 100644 index 00000000..a703bc28 --- /dev/null +++ b/docs/hypertools.align.procrustes.rst @@ -0,0 +1,6 @@ +hypertools.align.procrustes +=========================== + +.. currentmodule:: hypertools.align + +.. autofunction:: procrustes \ No newline at end of file diff --git a/docs/hypertools.impute.rst b/docs/hypertools.impute.rst new file mode 100644 index 00000000..1d5e569e --- /dev/null +++ b/docs/hypertools.impute.rst @@ -0,0 +1,6 @@ +hypertools.impute +================= + +.. currentmodule:: hypertools + +.. autofunction:: impute \ No newline at end of file diff --git a/docs/hypertools.predict.rst b/docs/hypertools.predict.rst new file mode 100644 index 00000000..e71b891e --- /dev/null +++ b/docs/hypertools.predict.rst @@ -0,0 +1,6 @@ +hypertools.predict +================== + +.. currentmodule:: hypertools + +.. autofunction:: predict \ No newline at end of file diff --git a/docs/hypertools.tools.cluster.rst b/docs/hypertools.tools.cluster.rst deleted file mode 100644 index 5f197d2b..00000000 --- a/docs/hypertools.tools.cluster.rst +++ /dev/null @@ -1,6 +0,0 @@ -hypertools.tools.cluster -======================== - -.. currentmodule:: hypertools.tools - -.. autofunction:: cluster \ No newline at end of file diff --git a/docs/hypertools.tools.load.rst b/docs/hypertools.tools.load.rst deleted file mode 100644 index 6668815b..00000000 --- a/docs/hypertools.tools.load.rst +++ /dev/null @@ -1,6 +0,0 @@ -hypertools.tools.load -===================== - -.. currentmodule:: hypertools.tools - -.. autofunction:: load \ No newline at end of file diff --git a/docs/hypertools.tools.procrustes.rst b/docs/hypertools.tools.procrustes.rst deleted file mode 100644 index 2ef07326..00000000 --- a/docs/hypertools.tools.procrustes.rst +++ /dev/null @@ -1,6 +0,0 @@ -hypertools.tools.procrustes -=========================== - -.. currentmodule:: hypertools.tools - -.. autofunction:: procrustes \ No newline at end of file diff --git a/docs/hypertools.tools.reduce.rst b/docs/hypertools.tools.reduce.rst deleted file mode 100644 index 8a8b31c9..00000000 --- a/docs/hypertools.tools.reduce.rst +++ /dev/null @@ -1,6 +0,0 @@ -hypertools.tools.reduce -======================= - -.. currentmodule:: hypertools.tools - -.. autofunction:: reduce \ No newline at end of file diff --git a/docs/images/v1.0-anim-fix/animate_legend_after.png b/docs/images/v1.0-anim-fix/animate_legend_after.png new file mode 100644 index 00000000..0b64d1c0 Binary files /dev/null and b/docs/images/v1.0-anim-fix/animate_legend_after.png differ diff --git a/docs/images/v1.0-anim-fix/save_movie_after_t3.6.png b/docs/images/v1.0-anim-fix/save_movie_after_t3.6.png new file mode 100644 index 00000000..a72e5a63 Binary files /dev/null and b/docs/images/v1.0-anim-fix/save_movie_after_t3.6.png differ diff --git a/docs/images/v1.0-anim-fix/save_movie_before_t3.6.png b/docs/images/v1.0-anim-fix/save_movie_before_t3.6.png new file mode 100644 index 00000000..05bf577e Binary files /dev/null and b/docs/images/v1.0-anim-fix/save_movie_before_t3.6.png differ diff --git a/docs/images/v1.0-anim-fix/spin_before.png b/docs/images/v1.0-anim-fix/spin_before.png new file mode 100644 index 00000000..250ae4cf Binary files /dev/null and b/docs/images/v1.0-anim-fix/spin_before.png differ diff --git a/docs/images/v2.0-animations/INDEX.md b/docs/images/v1.0-animations/INDEX.md similarity index 89% rename from docs/images/v2.0-animations/INDEX.md rename to docs/images/v1.0-animations/INDEX.md index 502461d5..ea1822dd 100644 --- a/docs/images/v2.0-animations/INDEX.md +++ b/docs/images/v1.0-animations/INDEX.md @@ -1,4 +1,4 @@ -# Animation export evidence (hypertools 2.0) +# Animation export evidence (hypertools 1.0) Sample animations exported via `hyp.plot(..., save_path=...)`; the extension picks the format (.gif / .png [APNG] / .mp4). diff --git a/docs/images/v2.0-animations/matplotlib_spin.gif b/docs/images/v1.0-animations/matplotlib_spin.gif similarity index 100% rename from docs/images/v2.0-animations/matplotlib_spin.gif rename to docs/images/v1.0-animations/matplotlib_spin.gif diff --git a/docs/images/v2.0-animations/matplotlib_window.gif b/docs/images/v1.0-animations/matplotlib_window.gif similarity index 100% rename from docs/images/v2.0-animations/matplotlib_window.gif rename to docs/images/v1.0-animations/matplotlib_window.gif diff --git a/docs/images/v2.0-animations/plotly_spin.gif b/docs/images/v1.0-animations/plotly_spin.gif similarity index 100% rename from docs/images/v2.0-animations/plotly_spin.gif rename to docs/images/v1.0-animations/plotly_spin.gif diff --git a/docs/images/v2.0-animations/plotly_window.gif b/docs/images/v1.0-animations/plotly_window.gif similarity index 100% rename from docs/images/v2.0-animations/plotly_window.gif rename to docs/images/v1.0-animations/plotly_window.gif diff --git a/docs/images/v2.0-animations/shapes_morph.mp4 b/docs/images/v1.0-animations/shapes_morph.mp4 similarity index 100% rename from docs/images/v2.0-animations/shapes_morph.mp4 rename to docs/images/v1.0-animations/shapes_morph.mp4 diff --git a/docs/images/v2.0-animations/shapes_morph_preview.gif b/docs/images/v1.0-animations/shapes_morph_preview.gif similarity index 100% rename from docs/images/v2.0-animations/shapes_morph_preview.gif rename to docs/images/v1.0-animations/shapes_morph_preview.gif diff --git a/docs/images/v2.0-animations/weights_hyperaligned.gif b/docs/images/v1.0-animations/weights_hyperaligned.gif similarity index 100% rename from docs/images/v2.0-animations/weights_hyperaligned.gif rename to docs/images/v1.0-animations/weights_hyperaligned.gif diff --git a/docs/images/v1.0-docs/01_gallery_index.png b/docs/images/v1.0-docs/01_gallery_index.png new file mode 100644 index 00000000..3ab76ae3 Binary files /dev/null and b/docs/images/v1.0-docs/01_gallery_index.png differ diff --git a/docs/images/v1.0-docs/01_gallery_index_thumb_0.png b/docs/images/v1.0-docs/01_gallery_index_thumb_0.png new file mode 100644 index 00000000..2b277496 Binary files /dev/null and b/docs/images/v1.0-docs/01_gallery_index_thumb_0.png differ diff --git a/docs/images/v1.0-docs/01_gallery_index_thumb_1.png b/docs/images/v1.0-docs/01_gallery_index_thumb_1.png new file mode 100644 index 00000000..d99605d5 Binary files /dev/null and b/docs/images/v1.0-docs/01_gallery_index_thumb_1.png differ diff --git a/docs/images/v1.0-docs/01_gallery_index_thumb_2.png b/docs/images/v1.0-docs/01_gallery_index_thumb_2.png new file mode 100644 index 00000000..31fde3c8 Binary files /dev/null and b/docs/images/v1.0-docs/01_gallery_index_thumb_2.png differ diff --git a/docs/images/v1.0-docs/01_gallery_index_thumb_3.png b/docs/images/v1.0-docs/01_gallery_index_thumb_3.png new file mode 100644 index 00000000..81538f70 Binary files /dev/null and b/docs/images/v1.0-docs/01_gallery_index_thumb_3.png differ diff --git a/docs/images/v1.0-docs/01_gallery_index_thumb_4.png b/docs/images/v1.0-docs/01_gallery_index_thumb_4.png new file mode 100644 index 00000000..b6a95619 Binary files /dev/null and b/docs/images/v1.0-docs/01_gallery_index_thumb_4.png differ diff --git a/docs/images/v1.0-docs/02_plot_basic.png b/docs/images/v1.0-docs/02_plot_basic.png new file mode 100644 index 00000000..0c647670 Binary files /dev/null and b/docs/images/v1.0-docs/02_plot_basic.png differ diff --git a/docs/images/v1.0-docs/02_plot_basic_crop.png b/docs/images/v1.0-docs/02_plot_basic_crop.png new file mode 100644 index 00000000..db94870e Binary files /dev/null and b/docs/images/v1.0-docs/02_plot_basic_crop.png differ diff --git a/docs/images/v1.0-docs/03_animate_spin.png b/docs/images/v1.0-docs/03_animate_spin.png new file mode 100644 index 00000000..d5d6c9b4 Binary files /dev/null and b/docs/images/v1.0-docs/03_animate_spin.png differ diff --git a/docs/images/v1.0-docs/03_animate_spin_frame.png b/docs/images/v1.0-docs/03_animate_spin_frame.png new file mode 100644 index 00000000..511214be Binary files /dev/null and b/docs/images/v1.0-docs/03_animate_spin_frame.png differ diff --git a/docs/images/v1.0-docs/04_animate_plotly.png b/docs/images/v1.0-docs/04_animate_plotly.png new file mode 100644 index 00000000..73b67232 Binary files /dev/null and b/docs/images/v1.0-docs/04_animate_plotly.png differ diff --git a/docs/images/v1.0-docs/04_animate_plotly_plot.png b/docs/images/v1.0-docs/04_animate_plotly_plot.png new file mode 100644 index 00000000..79830bf6 Binary files /dev/null and b/docs/images/v1.0-docs/04_animate_plotly_plot.png differ diff --git a/docs/images/v1.0-docs/05_plot_shape_morph.png b/docs/images/v1.0-docs/05_plot_shape_morph.png new file mode 100644 index 00000000..21a2d332 Binary files /dev/null and b/docs/images/v1.0-docs/05_plot_shape_morph.png differ diff --git a/docs/images/v1.0-docs/05_plot_shape_morph_frame.png b/docs/images/v1.0-docs/05_plot_shape_morph_frame.png new file mode 100644 index 00000000..fbb3c413 Binary files /dev/null and b/docs/images/v1.0-docs/05_plot_shape_morph_frame.png differ diff --git a/docs/images/v1.0-docs/06_plot_clusters.png b/docs/images/v1.0-docs/06_plot_clusters.png new file mode 100644 index 00000000..ec68901f Binary files /dev/null and b/docs/images/v1.0-docs/06_plot_clusters.png differ diff --git a/docs/images/v1.0-docs/06_plot_clusters_crop.png b/docs/images/v1.0-docs/06_plot_clusters_crop.png new file mode 100644 index 00000000..fc23a4e8 Binary files /dev/null and b/docs/images/v1.0-docs/06_plot_clusters_crop.png differ diff --git a/docs/images/v1.0-docs/07_tutorial_plot.png b/docs/images/v1.0-docs/07_tutorial_plot.png new file mode 100644 index 00000000..b3f6f582 Binary files /dev/null and b/docs/images/v1.0-docs/07_tutorial_plot.png differ diff --git a/docs/images/v1.0-docs/07_tutorial_plot_crop.png b/docs/images/v1.0-docs/07_tutorial_plot_crop.png new file mode 100644 index 00000000..caf958c3 Binary files /dev/null and b/docs/images/v1.0-docs/07_tutorial_plot_crop.png differ diff --git a/docs/images/v1.0-docs/08_tutorial_align.png b/docs/images/v1.0-docs/08_tutorial_align.png new file mode 100644 index 00000000..5f5a9776 Binary files /dev/null and b/docs/images/v1.0-docs/08_tutorial_align.png differ diff --git a/docs/images/v1.0-docs/08_tutorial_align_crop.png b/docs/images/v1.0-docs/08_tutorial_align_crop.png new file mode 100644 index 00000000..4d804c62 Binary files /dev/null and b/docs/images/v1.0-docs/08_tutorial_align_crop.png differ diff --git a/docs/images/v1.0-docs/PR_EVIDENCE.md b/docs/images/v1.0-docs/PR_EVIDENCE.md new file mode 100644 index 00000000..e4aefb32 --- /dev/null +++ b/docs/images/v1.0-docs/PR_EVIDENCE.md @@ -0,0 +1,116 @@ +# PR Evidence — HyperTools 1.0 Refactor (`dev-1.0-refactor`) + +Factual summary of the class-based refactor (Plans 1-7) and docs migration (Plan 8), +assembled for the PR into `dev-1.0`. `dev-1.0..HEAD` = 55 commits. + +## Test counts + +- Baseline (pre-refactor, `dev-1.0`, pandas 2.3.3): **242 passed**. +- After Plans 1-7 (class-based refactor complete, dw 0.5.0 / pandas 3.0.3): **318 passed**, + 0 failed (independent controller gate run `b7tw3iusu`, 12m30s). +- After Plan 8 (docs migration + Jeremy's 4 review fixes, incl. the gif full-frame-pacing + fix and its regression test): **325 passed** + the gif-pacing test + (`test_animation_export`, 9 passed in that file), 0 failed. +- This task (Plan 8 Task 5) added no library tests — it is a docs-verification script only + (`scripts/verify_docs_playwright.py`) and does not touch `hypertools/` or `tests/`. + +## Dependency upgrade + +- `datawrangler` (`pydata-wrangler`) **0.4.0 -> 0.5.0**. Upgrade fixed dw#30/#31 + (pandas-3 type-detection in `is_dataframe`/`is_multiindex_dataframe` breaking + `stack`/`unstack`). +- The **`pandas<3` ceiling has been lifted**. `pyproject.toml` now declares + `pandas>=2.2.0` (no upper bound) and `pydata-wrangler>=0.5.0`. CI (`test.yml`) gained a + pinned-pandas-3 acceptance gate on ubuntu/py3.12. Verified on both dw0.5/pandas2.3.3 and + dw0.5/pandas3.0.3 with 0 regressions. + +## Geo (`DataGeometry`) removal + +- `hyp.plot()` now returns a plain `matplotlib.figure.Figure` (static / plotly) or + `(fig, animation)` for matplotlib animations, instead of a `DataGeometry`. + `return_model=True` bundles `{'fig', 'models', 'xform_data'}`. +- `hyp.load()` now returns **raw/analyzed data** directly (list of arrays / DataFrame), + not a `DataGeometry`. +- `DataGeometry` is **hidden**: trimmed to a minimal internal unpickle-only class at its + original import path (`hypertools/datageometry.py`, ~30 lines) so the 6 hosted + legacy-pickle example datasets (spiral/weights/weights_avg/weights_sample/mushrooms/wiki) + still unpickle correctly. It is no longer exported as `hyp.DataGeometry` and carries an + "internal, not public API" docstring. Streaming plots (`hyp.plot()` on a stream) attach a + `fig.stream_info` dict (`data`, `xform_data`, `n_samples`, `reduce_model`, `truncated`) + to the returned `Figure` instead of mutating a geo. +- All 9 dead `tools/*.py` compatibility shims (`apply_model`, `cluster`, `colors`, + `describe`, `load`, `procrustes`, `reduce`, `sources`, `streaming`) were deleted; the 7 + real ones (`align`, `analyze`, `df2mat`, `format_data`, `missing_inds`, `normalize`, + `text2mat`) remain as the documented classic-callable API surface. + +## Jeremy's 4 review fixes (docs review pass, 2026-07-04) + +1. **3D legend clipped off-canvas** — legend was always placed to the right, but long + labels pushed it past the plot's x1 boundary; fixed layout so it stays in-canvas on + both backends. +2. **No gallery example for shape morphing** — added `examples/plot_shape_morph.py` + (zoo-shape morph animation), referencing the existing + `scripts/generate_shape_morph.py` asset pipeline. +3. **Plotly `','` format string rendered as solid lines, not markers** — root-caused to + `plotly_backend.py`'s `_MARKER_SYMBOLS` table being a hand-picked subset of matplotlib + marker characters that omitted `,` (and `1 2 3 4 8 P X | _`); completed the table from + `matplotlib.lines.Line2D.markers` so all 24 mpl marker chars map to Plotly + `mode='markers'`. This directly affects Colab, since Colab's HTML output defaults to the + plotly backend. +4. **Exported GIFs ~6x too fast** — animation export (both plotly and matplotlib backends) + was subsampling frames for file size without compensating per-frame delay, collapsing + total playback time (e.g., 75 frames / 4.5s instead of the intended ~27-30s). Fixed to + export the **full frame set** with correct per-frame delay (frame subsampling now only + applies to interactive HTML embedding, not exported GIF/MP4 files). Added a regression + test (`test_animation_export`) asserting exported animation duration matches the + requested duration. + +## Doc build + media validity + +- `PATH=.venv/bin:$PATH make -C docs html` — build succeeded, 0 tracebacks, all + example/tutorial pages generated under `docs/_build/html/`. +- All embedded `.mp4` files are `ffprobe`-valid (6 x ~30s clips, confirmed at Plan 8 Task 4 + close, including the new `plot_shape_morph` clip). +- Gallery GIFs are full-length (not subsampled) per the fix above; the reference + `docs/auto_examples/spin.gif` committed artifact (900 frames / ~27-30s) was refreshed + after being found stale. + +## Playwright visual verification (this task) + +`scripts/verify_docs_playwright.py` serves the already-built `docs/_build/html/` tree over +a real local `http.server` and drives it with a real headless Chromium (Playwright +1.61.0 / Chrome for Testing 149.0.7827.55) — no mocks, no stubs. It makes hard, +non-weakened assertions against the live DOM and exits non-zero on any failure. + +Run: `.venv/bin/python scripts/verify_docs_playwright.py` — **8/8 pages passed**: + +| Page | Kind | Key assertions | +|-|-|-| +| `auto_examples/index.html` | gallery index | 40 thumbnails (>= 20 required); 5 sampled thumbnails non-blank (pixel stddev 15.3-36.0) | +| `auto_examples/plot_basic.html` | static example | `sphx_glr` image decodes to 640x480, non-blank (std 35.1); Colab badge present, href branch-aware | +| `auto_examples/animate_spin.html` | animated (mp4) | `