anyplotlib.Plot2D#
- class anyplotlib.Plot2D(data, x_axis=None, y_axis=None, units='px', cmap=None, vmin=None, vmax=None, origin='upper', gpu='auto', tile='auto', integration_method='mean', overview_method='mean', tile_backend=None)[source]#
Bases:
_BasePlot,_PanelMixin,_MarkerMixin2-D image plot panel.
Not an anywidget. Holds state in
_statedict; every mutation calls_push()which writes to the parent Figure’s panel trait.- The marker API follows matplotlib conventions:
plot.add_circles(offsets, name=”g1”, facecolors=”#f00”, radius=5) plot.markers[“circles”][“g1”].set(radius=8)
- Parameters:
- TILE_THRESHOLD = 1024#
- OVERVIEW_MAX = 1024#
- VIEW_OVERFETCH = 2.0#
- VIEW_ZOOM_MIN = 1.05#
- RANGE_SAMPLE_MAX = 2048#
- property gpu_active: bool#
True when this image is being rendered by the WebGPU path (reported by JS after the device resolves and the panel flips to GPU).
Falseon the Canvas2D path (small image, gpu=False, no GPU, or a GPU failure/fallback).
- enable_tile(backend=None, integration_method='mean', overview_method=None)[source]#
Turn tile mode ON (or reconfigure it) AFTER construction — for a consumer whose large frame isn’t known at
imshowtime (e.g. a live navigator whose signal frame arrives later and changes). Registers the internal view→tile loop (once), sets the logical size from the backend, and paints the overview base. Callupdate_tile_source(new_frame)on each subsequent data change.backend: a TileBackend (or an ndarray, wrapped).Nonekeeps the current backend (just re-enable / change method).overview_method: sampling method for the base overview texture ("mean"|"subsample"|"max").Nonekeeps the current setting (default"mean"from construction). Use"subsample"to restore the old fast nearest-neighbour path when a full-frame area-mean is too expensive.
- update_tile_source(array=None)[source]#
The backing DATA changed (e.g. a movie navigator advanced a frame) — keep the current zoom/subselection but refresh the pixels. Re-samples the overview base AND (if a detail tile is currently shown) the SAME detail region from the new data, so a live source updates in place without a view change.
array: swap the numpy backend’s source first (convenience for the common ndarray case). For a custom backend that already mutated its own source, callupdate_tile_source()with no argument to just re-sample.- Return type:
None
- to_state_dict()[source]#
Return a JSON-serialisable copy of the current state.
On the binary-transport path
_state["image_b64"]may hold a tiny"\x00bin:<checksum>"change-token instead of a base64 string — the real pixels ride the PLOTBIN channel (_electron._route_changereads them from the Figure’s_raw_pixelsside-table). The token is the correct WIRE representation and is passed through untouched here so the hotFigure._pushpath does NOT re-encode base64 every frame.A COLD consumer with no binary channel (
save_html/ standalone / Jupyter) must instead materialise real base64; it callsresolve_pixel_tokens()on the returned dict (Figure._pushdoes this for the standalone trait when binary transport is off).- Return type:
- resolve_pixel_tokens(d)[source]#
Replace any
"\x00bin:…"pixel change-token in d with the real base64 (materialised from the Figure’s_raw_pixelsside-table), in place, and return d. Used by the COLD paths (save_html / standalone) that have no PLOTBIN channel and need the pixels inline. A no-op for a normal base64 string. Seeto_state_dict().Also materialises every LAYER’s pixels: each layer has a top-level geom key
layer_<id>_b64AND a mirrorimage_b64field inside itslayersentry — both are resolved so asave_htmlsnapshot of a layered plot is self-contained.
- property data: ndarray#
The image data in the original user coordinate system (read-only).
Returns a float64 copy with
writeable=False. To replace the data callset_data().The float64 cast happens HERE, lazily, not in
set_data— a scrub pushes a new frame every tick but rarely reads.databack, and a full float64 copy of a 4k frame is ~12 ms.set_datakeeps the frame in its source dtype (self._data); we cast + copy only on the (rare) read.
- set_data(data, x_axis=None, y_axis=None, units=None, clim=None, tile=None)[source]#
Replace the image data.
The
originsupplied at construction is automatically re-applied so the new data is displayed with the same orientation.tile— per-call override of the tile decision (defaultNoneuses the plot’s construction preference).Falseforces a PLAIN full-frame push even for a large frame (the caller manages its own decimation);Trueforces tile mode. A live consumer that only wants tiling on some frames (e.g. only when its GPU is active, sending the NATIVE frame then, but a pre-decimated frame otherwise) passestile=Falseon the decimated frames so they don’t get auto-tiled at the wrong logical size.clim— optional(vmin, vmax)display range applied in the SAME push as the new data. Without it the caller must follow with a separateset_clim, which pushes a SECOND time: the first push shows the image stretched over its full data range (wrong contrast) and the second corrects it, producing a one-frame flash on every update. Passingclimhere makes data + contrast a single atomic frame (no flash).- Raises:
ValueError – If
datahas an invalid shape/ndim, or if this plot has image layers (add_layer()) anddata’s(H, W)differs from the current image shape. A layer keeps the size it had when it was added/last updated, so a shape-changing base update would silently stretch stale-sized layer pixels over the new image. Remove all layers (remove_layer) before changing the base image’s shape, then re-add them at the new size.- Parameters:
- Return type:
None
- set_overlay_mask(mask, color='#ff4444', alpha=0.4)[source]#
Set (or clear) a transparent boolean mask drawn over the image.
The mask is composited client-side in the browser at alpha opacity using color for all
Truepixels. Call withmask=Noneto remove any existing overlay.- Parameters:
mask (ndarray of shape (H, W), bool or uint8, or None) – Boolean array aligned to the image data.
True/ non-zero pixels are filled with color at transparency alpha. PassNoneto clear the overlay.color (str, optional) – CSS hex colour for the overlay, e.g.
"#ff4444". Default red. Must be in#RRGGBBformat.alpha (float, optional) – Opacity in [0, 1]. Default 0.4 (40 % opaque).
- Return type:
None
- property layers: list#
The list of
Layerhandles, in z-order (index 0 drawn first, above the base image).
- add_layer(data, *, cmap='magma', alpha=0.5, clim=None, visible=True, tint=None)[source]#
Add an image LAYER drawn over the base image.
Each layer has its OWN colormap, display range (
clim), and opacity (alpha), and is composited on top of the base image (and previously added layers) with the SAME zoom/pan transform, so it tracks the base exactly. This is the multi-image overlay primitive; for a single-colour boolean mask useset_overlay_mask()instead.- Parameters:
data (ndarray, shape (H, W)) – 2-D scalar array, the same size as the base image. Normalised to uint8 via
clim→ LUT exactly like the base image. A shape mismatch raisesValueError.cmap (str, optional) – Colormap name (default
"magma"). Ignored for display whiletintis set (the tint LUT replaces the colormap), but kept soset(cmap=...)can revert to it.alpha (float, optional) – Opacity in [0, 1] (default
0.5).clim ((vmin, vmax) or None, optional) – Display range;
None(default) auto-scales to the data min/max.visible (bool, optional) – Whether the layer is drawn (default
True).tint (str or None, optional) – A
#rgb/#rrggbbhex colour. When set, the layer renders as a clear→colour intensity ramp instead of a named colormap: RGB is tint at every intensity and per-texel alpha ramps linearly 0 → 255 (transparent at low intensity → opaque tint at high). The per-texel alpha multiplies with the layer’salpha.None(default) keeps the named-colormap behaviour. An invalid colour raisesValueError.
- Returns:
A handle with
.set(...)/.set_data(frame)/.remove().- Return type:
Layer
- Raises:
RuntimeError – If the plot is in TILE mode — layers are incompatible with tiling (a layer would have to be tiled independently against the same view). Load the plot with
tile=Falseto use layers.ValueError – If
datais not 2-D or does not match the base image size.
- set_clim(vmin=None, vmax=None)[source]#
Set the display range. Because scalar frames are quantised to uint8 over their clim (so a hot pixel / zero beam can’t crush the signal — see _normalize_image), a new range is honoured by RE-QUANTISING from the cached raw frame, not merely re-windowing the existing codes (which are saturated outside the previous band and so couldn’t widen past it). For an RGB frame (no scalar quantisation) or when no raw frame is cached, fall back to a pure display-window update.
- Return type:
None
- set_detail(tile=None, x0=None, x1=None, y0=None, y1=None)[source]#
Upload a HIGH-RES detail tile covering the LOGICAL image-pixel rectangle
[x0:x1, y0:y1]of the base image (in the SAME orientation as the frame passed toset_data— alreadyorigin-applied), so a zoom-in shows true native pixels for the visible region WITHOUT transferring the whole full-res frame. The shader samples this tile instead of the base whenever the current zoom window lies inside[x0:x1, y0:y1]; otherwise it falls back to the base texture.set_detail(None)clears it (revert to base).tileis quantised to uint8 over the SAME display range as the base (display_min/display_max) so its contrast matches seamlessly — a zoom crop must look identical to the base, just sharper. Only meaningful for scalar (non-RGB) images.- Return type:
None
- set_ylabel(label, fontsize=None)[source]#
Set the y-axis label. Same semantics as
set_xlabel().
- set_extent(x_axis, y_axis, units=None)[source]#
Recalibrate the image axes to the given coordinate arrays.
Sets
has_axesso the front-end draws physical tick gutters + the scale bar — the same gateset_data(x_axis=, y_axis=)sets. Without this a tiled image (which is calibrated ONLY throughset_extent/enable_tile, never throughset_datawith axis args) would show no ticks and no scale bar (thehas_axesgate stayed False). Passunitsto update the scale-bar unit label in the same push.- Parameters:
units (str | None)
- Return type:
None
- set_colorbar_label(label, fontsize=None)[source]#
Set the colorbar label (mini-TeX allowed; default size 10 px).
- set_colorbar_pad(pad)[source]#
Set the gap in px between the image and the colorbar strip.
- Parameters:
pad (float or None) – Gap in CSS pixels.
Nonerestores the default (6 px). The gap comes out of the image width, so widening it shrinks the image rather than pushing the strip off the panel.- Return type:
None
- set_scalebar_style(color=None, bgcolor=None)[source]#
Recolour the automatic scale bar.
The scale bar appears on its own whenever the panel has calibrated axes (
unitsother than"px"). It defaults to white on a translucent dark pill, which reads well on most images but not on a light one.- Parameters:
- Return type:
None
Examples
>>> plot.set_scalebar_style(color="black", bgcolor="none")
- add_widget(kind, color='#00e5ff', **kwargs)[source]#
Add an overlay widget by kind name.
Dispatches to the dedicated
add_<kind>_widgetmethod. Supported kinds:"circle","rectangle","annular","polygon","crosshair","label","arrow","line","brush","vline","hline".Every kind also accepts
show_handles(defaultTrue) to toggle the grab-handle dots without changing hit-testing / draggability.vline/hlinehave no handles — the whole line is the grab target — so they ignore it, and neither doesbrush(a freehand stroke has no grab point).
- add_circle_widget(cx=None, cy=None, r=None, color='#00e5ff', linewidth=2, show_handles=True)[source]#
Add a draggable circle overlay.
- add_rectangle_widget(x=None, y=None, w=None, h=None, color='#00e5ff', linewidth=2, show_handles=True, max_extent=None)[source]#
Add a draggable rectangle overlay.
max_extentcaps the rectangle’s size in the widget’s coordinates — a scalar caps both axes, a(max_w, max_h)pair caps them separately. The rectangle then physically stops growing at the cap while dragging (the dragged corner pins, the opposite corner stays put).
- add_annular_widget(cx=None, cy=None, r_outer=None, r_inner=None, color='#00e5ff', linewidth=2, show_handles=True)[source]#
Add a draggable annular (ring) overlay.
- add_polygon_widget(vertices=None, color='#00e5ff', linewidth=2, show_handles=True)[source]#
Add a draggable polygon overlay.
- Parameters:
- Return type:
- add_brush_widget(radius=None, color='#00e5ff', colors=None, class_id=0, strokes=None, stroke_classes=None, alpha=0.6, active=True, erase=False)[source]#
Add a freehand paint-brush overlay for labelling regions.
Shift + drag paints a stroke; a bare drag still pans the image and still drags other widgets. One brush can hold several label classes at once — a stroke is tagged with the widget’s current
class_idand drawn incolors[class_id].Painting is modal: while the brush is armed, a Shift-press over the image no longer emits a panel
pointer_down, so a host that binds Shift-click to something else needs a different modifier (oractive=Falsewhile that mode is on). A Shift-drag starting in the axis margin is not a brush gesture and pans as usual.The stroke accumulates in the browser and reaches Python once, on release, as a
pointer_upevent —pointer_movedoes not fire for a brush. SeeBrushWidget.- Parameters:
radius (float, optional) – Brush radius in image pixels; the painted band is
2 * radiuswide. Defaults to 2 % of the smaller image dimension (at least 2), so the default is visible on a 4096² image and usable on a 64² one.color (str, optional) – CSS colour for classes not covered by
colors. Default"#00e5ff".colors (list of str, optional) – Per-class CSS colours, indexed by
class_id.class_id (int, optional) – Label class new strokes are tagged with. Default 0.
strokes (list, optional) – Pre-existing strokes
[[[x, y], ...], ...]in image pixels.stroke_classes (list of int, optional) – Class id per entry of
strokes; must be the same length.alpha (float, optional) – Stroke opacity. Default 0.6, so the labelled feature stays visible underneath.
active (bool, optional) – Accept Shift-drag painting. Default
True;Falseparks the tool with its strokes still drawn.erase (bool, optional) – Armed drags remove stroke points within
radiusinstead of painting. DefaultFalse.
- Returns:
Widget object.
widget.strokes/widget.stroke_classeshold the painted geometry;clear_strokes()andstrokes_for_class()manage it.- Return type:
BrushWidget
- add_crosshair_widget(cx=None, cy=None, color='#00e5ff', linewidth=2, show_handles=True)[source]#
Add a draggable crosshair overlay.
- add_label_widget(x=None, y=None, text='Label', fontsize=14, color='#00e5ff', show_handles=True)[source]#
Add a draggable text label overlay.
- add_arrow_widget(x=None, y=None, u=None, v=None, color='#00e5ff', linewidth=2, show_handles=True)[source]#
Add a draggable arrow overlay (tail at
(x, y), head at(x + u, y + v)). Defaults place the tail at 25 %, 25 % of the image with a vector of 15 % of the image size, mirroringadd_label_widget()’s defaulting.
- add_line_widget(x1=None, y1=None, x2=None, y2=None, color='#00e5ff', linewidth=2, show_handles=True)[source]#
Add a draggable two-endpoint line segment overlay.
A bare segment with a grab handle at each end — no arrowhead (see
add_arrow_widget()) and no closed path (seeadd_polygon_widget()). Use it for a line profile, a cross-section cut, or a two-point measurement.- Parameters:
x1 (float, optional) – First endpoint in image coordinates. Defaults to 25 % of the image size.
y1 (float, optional) – First endpoint in image coordinates. Defaults to 25 % of the image size.
x2 (float, optional) – Second endpoint. Defaults to 75 % of the image size.
y2 (float, optional) – Second endpoint. Defaults to 75 % of the image size.
color (str, optional) – CSS colour string. Default
"#00e5ff".linewidth (float, optional) – Stroke width in px. Default 2.
show_handles (bool, optional) – Draw the endpoint grab handles. Default
True.
- Returns:
Widget object.
widget.lengthgives the segment length in data coordinates.- Return type:
LineWidget
- add_vline_widget(x=None, color='#00e5ff', linewidth=2)[source]#
Add a draggable full-height vertical line overlay.
The line spans the whole panel and is grabbable anywhere along its length, which makes it the right pointer for “select a column” — a crosshair pinned to one axis leaves a stray perpendicular line.
- Parameters:
- Return type:
- add_hline_widget(y=None, color='#00e5ff', linewidth=2)[source]#
Add a draggable full-width horizontal line overlay.
The row counterpart of
add_vline_widget(); grabbable anywhere along its length.- Parameters:
- Return type:
- set_view(x0=None, x1=None, y0=None, y1=None)[source]#
Set the viewport to a data-space rectangle.
- Parameters:
x0 (float, optional) – Horizontal data-space range to show. If omitted the full x-extent is used for zoom calculation.
x1 (float, optional) – Horizontal data-space range to show. If omitted the full x-extent is used for zoom calculation.
y0 (float, optional) – Vertical data-space range to show. If omitted the full y-extent is used for zoom calculation.
y1 (float, optional) – Vertical data-space range to show. If omitted the full y-extent is used for zoom calculation.
center_x (Translates the requested rectangle into the zoom /)
renderer. (/ center_y state values used by the 2-D JS)
- Return type:
None
- add_circles(offsets, name=None, *, radius=5, facecolors=None, edgecolors='#ff0000', linewidths=1.5, alpha=0.3, hover_edgecolors=None, hover_facecolors=None, labels=None, label=None, transform='data', clip_display=True, size_units='data')[source]#
Add circle markers at (x, y) positions in data coordinates.
size_units="px"pins radius to screen pixels so the circles keep their size through a zoom; the default"data"scales them with the data, as a shape drawn on the image does.- Parameters:
- Return type:
- add_points(offsets, name=None, *, sizes=5, color='#ff0000', facecolors=None, linewidths=1.5, alpha=0.3, hover_edgecolors=None, hover_facecolors=None, labels=None, label=None, transform='data', clip_display=True, size_units='data')[source]#
Add point markers at (x, y) positions in data coordinates.
A marker standing in for a point usually wants
size_units="px"so it does not grow with zoom — that is what matplotlib does, sizing scatter markers in display points.- Parameters:
- Return type:
- add_hlines(y_values, name=None, *, color='#ff0000', linewidths=1.5, hover_edgecolors=None, labels=None, label=None, transform='data', clip_display=True)[source]#
Add static horizontal lines at the given y positions.
- Parameters:
- Return type:
- add_vlines(x_values, name=None, *, color='#ff0000', linewidths=1.5, hover_edgecolors=None, labels=None, label=None, transform='data', clip_display=True)[source]#
Add static vertical lines at the given x positions.
- Parameters:
- Return type:
- add_arrows(offsets, U, V, name=None, *, edgecolors='#ff0000', linewidths=1.5, hover_edgecolors=None, labels=None, label=None, transform='data', clip_display=True)[source]#
- Parameters:
- Return type:
- add_ellipses(offsets, widths, heights, name=None, *, angles=0, facecolors=None, edgecolors='#ff0000', linewidths=1.5, alpha=0.3, hover_edgecolors=None, hover_facecolors=None, labels=None, label=None, transform='data', clip_display=True, size_units='data')[source]#
- Parameters:
- Return type:
- add_lines(segments, name=None, *, edgecolors='#ff0000', linewidths=1.5, hover_edgecolors=None, labels=None, label=None, transform='data', clip_display=True)[source]#
- Parameters:
- Return type:
- add_rectangles(offsets, widths, heights, name=None, *, angles=0, facecolors=None, edgecolors='#ff0000', linewidths=1.5, alpha=0.3, hover_edgecolors=None, hover_facecolors=None, labels=None, label=None, transform='data', clip_display=True, size_units='data')[source]#
- Parameters:
- Return type:
- add_squares(offsets, widths, name=None, *, angles=0, facecolors=None, edgecolors='#ff0000', linewidths=1.5, alpha=0.3, hover_edgecolors=None, hover_facecolors=None, labels=None, label=None, transform='data', clip_display=True, size_units='data')[source]#
- Parameters:
- Return type:
- add_polygons(vertices_list, name=None, *, facecolors=None, edgecolors='#ff0000', linewidths=1.5, alpha=0.3, hover_edgecolors=None, hover_facecolors=None, labels=None, label=None, transform='data', clip_display=True)[source]#
- Parameters:
- Return type: