Skip to content

Update documentation for 0.3.0 release#34

Merged
CSSFrancis merged 6 commits into
mainfrom
feat/hyperspy-parity-0.3.0
Jul 14, 2026
Merged

Update documentation for 0.3.0 release#34
CSSFrancis merged 6 commits into
mainfrom
feat/hyperspy-parity-0.3.0

Conversation

@CSSFrancis

Copy link
Copy Markdown
Owner

Add in documentation for the 0.3.0 release. This includes things like alternative tiling backends, gpu acceleration for plotting etc.

…notations

Add gallery examples covering features that were implemented but undocumented,
and export the two widgets that were missing from the top-level package.

Examples (all run headlessly + drive the interactive Pyodide path):
- PlotTypes/plot_tile_backend.py — custom TileBackend Protocol: pan/zoom a
  4.3-gigapixel procedural fractal that is generated tile-by-tile and never
  held in memory.
- PlotTypes/plot_twinx.py — secondary (right) y-axis via add_right_axis +
  add_line(axis="right") + set_right_ylim.
- PlotTypes/plot_gpu_voxels.py — ax.voxels(gpu="auto") WebGPU path with a
  PlaneWidget slice selector and gpu_active readback.
- PlotTypes/plot_step_and_log.py — step-mid linestyle + semilogy log y-axis.
- Markers/plot_transform_markers.py — transform="axes"/"display" anchored
  markers that stay put on zoom.
- Widgets/plot_widget2d_arrow.py, plot_widget1d_point.py,
  plot_widget3d_plane.py — the ArrowWidget, PointWidget and PlaneWidget.
- Interactive/plot_figure_annotations.py — figure-level annotation layer
  (set_figure_markers) + edit_chrome drag mode + double-click to annotate.

Also:
- anyplotlib/__init__.py — export ArrowWidget and PointWidget (were only in
  anyplotlib.widgets, missing from the top-level package __all__).
- docs/api/index.rst — add Line1D, ArrowWidget, PointWidget, PlaneWidget to
  the API reference autosummary.

Claude-Session: https://claude.ai/code/session_018MLraeaoQBWFDScg72W41h
Rewrite the example backend's escape loop for speed (it runs once per
pan/zoom, so responsiveness depends on it):

- real/imag float32 arithmetic instead of complex128 (half the memory
  traffic, no complex-multiply overhead);
- escape test |z|^2 > 4 instead of abs(z) > 2 (no sqrt);
- no shrinking boolean mask — count iterations each pixel stays inside via
  `counts += inside` (bool→uint add); escaped pixels run to inf harmlessly
  (inf fails the <=4 test) inside an np.errstate guard.

Measured: overview 800x600 ~600ms -> ~200ms (3x); a deep-zoom tile
~870ms -> ~106ms (8x) — the zoom case is where the old masked loop was
worst, since nothing escapes early so the mask never shrank.  Output is
bit-identical in structure (corr 1.0).

Claude-Session: https://claude.ai/code/session_018MLraeaoQBWFDScg72W41h
The example already qualified for the WebGPU image path (gpu_mode="auto" +
a 4.3-gigapixel logical size, far above the ~1 MP threshold; tiling does
not disable the GPU — _gpuDraw2dImage stitches the crisp detail tile over
the GPU-composited overview texture).  But nothing said so, and headless
renders (the static gallery thumbnail, CI) have no navigator.gpu and fall
back to Canvas2D, so it read as "not using the GPU".

Make it explicit and checkable:
- pass gpu="auto" on imshow;
- document that tiling + the GPU cooperate and why 4.3 GP crosses the auto
  threshold, and that headless builds fall back to Canvas2D;
- print v.gpu_active so the live "Run in browser" view confirms the path
  (gpu_status is an internal echo, not a user event — read the property).

Claude-Session: https://claude.ai/code/session_018MLraeaoQBWFDScg72W41h
Two fixes so the docs build is warning-clean:

- Line1D was added to the indexed autosummary in a previous commit, which
  duplicated its object descriptions against the plot classes' Full
  Reference block. Document it the same way as the other plot classes
  instead: list it in figure_plots.rst and autoclass it there with
  :no-index: (the convention the file already uses), and drop it from the
  index.rst autosummary. Removes the "duplicate object description of
  anyplotlib.Line1D.id" warning.

- Event.x/.y (pixel fields) and Plot1D.x/.y (data properties) share short
  names, so autodoc reported "more than one target found for
  cross-reference 'x'/'y'" — a pre-existing, harmless ambiguity (each is
  documented on its own page). Add a scoped `suppress_warnings =
  ["ref.python"]` with a comment; nitpicky stays off so genuinely missing
  refs still fail.

Verified: sphinx-build now reports "build succeeded." with no warnings.

Claude-Session: https://claude.ai/code/session_018MLraeaoQBWFDScg72W41h
Voxel cubes cost ~6x a scatter point on Canvas2D, and interactive volumes
re-slice (set_data on every plane drag), so the whole set re-rasterises per
frame.  A few thousand cubes already stutter on the CPU path, yet the old
"auto" threshold (8000) kept them on Canvas2D.  Drop it to 1000 so realistic
interactive volumes take the GPU instanced path by default.

This makes the voxel grain explorer example (a ~6.9k-cube slice that
re-slices on drag) GPU-accelerated under plain gpu="auto" — previously it
sat just under 8000 and crawled.  Reverted the per-example gpu="always"
workaround now that "auto" does the right thing.

Updated the two ax.voxels() docstrings (~8k -> ~1k).  scatter's threshold
(20000) is unchanged.  plot3d GPU tests still pass (they exercise
always/off/fallback, not the auto cutoff).

Claude-Session: https://claude.ai/code/session_018MLraeaoQBWFDScg72W41h
The explorer re-slices voxels + re-cuts three 2D image panels on every plane
drag, which is fine natively but sluggish under Pyodide.  Halving N in each
dimension quarters both the per-frame on-plane voxel count (6912 -> 1728) and
each 2D slice (48² -> 24²), so dragging stays responsive in the browser.

Still above the ~1k voxel threshold, so the WebGPU render path is retained.
Comments updated for the new counts.

Claude-Session: https://claude.ai/code/session_018MLraeaoQBWFDScg72W41h
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.18%. Comparing base (9b0878f) to head (b4f7953).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #34   +/-   ##
=======================================
  Coverage   90.18%   90.18%           
=======================================
  Files          39       39           
  Lines        3902     3902           
=======================================
  Hits         3519     3519           
  Misses        383      383           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@CSSFrancis CSSFrancis merged commit bf9d441 into main Jul 14, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants