Repository navigation
0.41.0 — Interactive Slice tool
Added
-
Interactive Slice tool for pcolormesh/imshow (
options=["slice"]).
Scrub any row or column of a mesh as a 1-D profile with a play/step
slider, toggle between the heatmap (with a dashed cursor) and the profile,
fix the value axis to auto / colorbar / custom bounds, and couple every
mesh sharing the same grid to one global slider with "Link all matching
axes" -- built for figures with hundreds of meshes, where per-axes link
checkboxes are not workable. Off until "Enable Slice" is checked; curvilinear
meshes are excluded (no single row/column to slice). -
Modular toolbar via
options=.to_html/save/show/
show_in_jupyter/Report.save(andPlotPressWidget) take
options=[...]for tools beyond the core toolbar (Pan/Zoom, Home, Fit
Width, Axes, Point Picking, Annotate, File), which every page keeps.
Nothing existing changes unless asked for. -
Slice companion panel. The Slice menu's profile can be drawn in a
strip carved out of the mesh's own axes (above it for an X slice, to its
left for a Y slice), beside the heatmap and aligned through every pan/zoom,
instead of replacing it. A radio in the menu switches between that
(the default), the profile replacing the heatmap, and a cursor-only heatmap.
Point Picking works on the strip -- a click pins the nearest profile sample
(x,y, value), which follows the slider and pan/zoom, steps with the
arrow keys (staying on the strip's edge, value in red, if it goes off the
range) -- and Snap pins to
slice (a checkbox in the menu's own "Slice view" group) links pins in both
directions: a heatmap pin gets a mirror on the shown profile, and a pin placed
on the profile gets one on the heatmap cell it points at. Extract ignores profile
pins and reports the heatmap cell instead (never the same cell twice). When profile pins are left out
(Snap off), the Extract panel warns and points to Snap pins to slice. The original stays
put and each pair shares a label color.
A colorbar attached to a sliced mesh shrinks to the heatmap's share of its axes
when the strip is above it, so the two stay aligned. -
A colorbar shared by several axes shrinks with their heatmaps when every one of
them gets a strip (it stays as drawn if only some do). -
Save / Save As keep the Slice state. A saved page reopens with Slice enabled,
in the same view and orientation, on the same chosen axes, with the same link/snap
settings, value range and slider position, and with its profile pins. -
Point Picking works on the "Profile replaces heatmap" view too. A click picks a
profile sample instead of a hidden heatmap cell, and pins carry across a switch
between the two profile views. -
The companion strip now works on more axes. Axes with fixed ticks
(set_xticks/set_yticks),axis("off"), and axes with atwinx/twiny
or secondary axes (which shrink together with their parent) get a strip too;
their static ticks are remapped to the smaller heatmap. An inset axes is left
out of Slice altogether, and the axes it sits on still gets just the cursor and
slider. Also
fixes a twin's ticks being redrawn on the wrong edge (and its parent's axis
doubled) when the view changed. -
Choose which axes to slice. The Slice menu has an "Axes to slice" radio --
All axes or Selected axes -- where selecting axes is done by clicking them on the
figure; only the chosen axes get a slider, cursor and strip,
and "Link all matching axes" couples just those. Theaxesstartup setting takes
the axes (or indices) to start with. -
Startup settings for a tool. Pass
optionsas a dict to start a tool in
a chosen state -- e.g.options={"slice": {"enabled": True, "view": "companion", "orientation": "y", "link_all": True, "range": "colorbar"}}--
rather than switched off; values are validated up front. -
Gridlines on the Slice profile. A "Gridlines on profile" checkbox (and a
gridstartup setting, default on) draws light lines on the strip and on the
profile-replaces-heatmap view at both the value ticks and the heatmap's own ticks. -
Docs: Slice examples. Four examples in the gridded-data gallery (a heatmap
row, columns with the replace view, linked meshes, chosen axes) and one at scale
(a thousand meshes). Every live pcolormesh/image figure in the plot-type
reference and real-application galleries now opens with Slice enabled, and an
example can set its own state with_gallery_interactive_options.
Performance
- Slice on a figure with ~1000 pcolormeshes. Enabling Slice went from ~14 s
(without "Link all") to under a second, a linked slider step from ~3 s to under
0.1 s, and view/orientation switches from 7-9 s to under 0.5 s. Choosing a subset
of axes stays at tens of milliseconds per step. The cost was layout thrashing
(measuring while writing) and per-axes scans of the whole document.
Changed
- The Extract panel now shows JSON by default, with CSV/JSON radios to switch
the text, and its "Copy CSV" button is now "Copy" (it copies whichever format is
showing). The two download buttons are unchanged. - New logo, docs sidebar image and favicon. Refreshed artwork for the three
images already wired in (assets/plotpress-logo.png,docs/_static/logo.png,
docs/_static/favicon.png); nothing that references them changed.
Fixed
- Slice: a strip could take more than its own axes. The strip's 28px
legibility floor ignored how tall the axes actually was, so on a stack of short
panels (14 rows in a 5in figure is ~23px each) it claimed more than the whole
rect and left the heatmap with a negative one -- which draws nothing at all,
silently, since a negative width/height raises no error. The floor now gives way
on an axes too small to hold both. - Slice: an all-NaN row showed the previous row's profile. Under "Profile
replaces heatmap", stepping onto a row with no values left the last row's line on
screen: the slider read row 4 while the profile plotted row 3. A pin on such a
slice likewise stayed visible, still reporting the value it last read. - Slice no longer fights the legend. Slice and the legend's click-to-hide
toggle both wrote a mesh's ownstyle.display, so a slider step brought back a
mesh the reader had just hidden. Each now has its own channel, and a mesh stays
hidden while either wants it hidden. - Tick labels stayed put through a zoom. Three long-standing divergences
between the labels Python renders and the ones the interactive view recomputes:
an axis with a fractionalset_xlocatorbase relabelled 0/2.5/5/7.5/10 as
0/3/5/8/10 after the first pan; a lone tick at 0 rendered0e0; and a tick at
exactly +-0.5 read0/-0as drawn but1/-1once zoomed, because
JavaScript rounds a halfway value away from zero where Python rounds half to
even. A new 2,707-case parity sweep (tests/test_tick_parity_node.py) covers
the whole range x locator x format x date x categorical x log grid. - Tick positions land on their exact step multiples.
nice_ticksand
multiple_ticksaccumulated their step by repeated addition, so a tick that
should be 5.5 came out at 5.499999999999998 and one that should be 0 at
-3.4e-13 -- the latter printed as a literal-3.4e-13axis label in the static
SVG.