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, probe_exact=True, probe_ms=250)[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#
- set_readout_visible(visible)[source]#
Show or hide the on-image hover readout (the pill naming the physical position, the pixel index and the pixel value).
Hiding it does NOT stop the readout being computed: an embedding host still receives every update through
mount()’sopts.onReadoutcallback and theapl:readoutDOM event, so an Electron app can render the same text in its own status line (e.g. the bottom-right of the window) where it covers no data. Seedocs/embedding.rst.- Parameters:
visible (bool)
- Return type:
None
- set_value_probe(enabled=True, ms=250)[source]#
Enable/disable the EXACT-value probe behind the hover readout (on by default;
Plot2D(..., probe_exact=False)opts out at construction).The value the renderer can compute locally comes from the 8-bit codes it draws, so it is exact for integer data whose range fits 255 levels and quantised to
range/255otherwise. With the probe on, the renderer asks Python for the true value once the cursor has DWELLEDmsmilliseconds on a pixel; the answer replaces the estimate in place. It costs one small message per dwelled-on pixel — never one per mouse move — and degrades silently to the local estimate when there is no live kernel (asave_htmlpage) or the kernel is busy.ms=0(orenabled=False) disables it.
- 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
- set_tile_band(vmin, vmax)[source]#
PIN the fixed quantisation band the tile bytes are encoded over.
Tile mode normally derives this band once, from the full-res data (see
enable_tile), and then holds it: a contrast change re-windows in the LUT with no pixel re-encode or re-transfer. A live consumer that already KNOWS the honest range — a camera’s bit depth, a detector’s saturation point — can pin it here instead of letting the first frame decide, so the contrast doesn’t shift when a later frame happens to contain a brighter pixel.Pinning also survives what auto-derivation cannot: a source whose first frames are flat (a placeholder, a closed shutter) has no range to derive from, and the band stays unset until a frame with real content arrives.
Re-samples the overview (and any active detail tile) over the new band in a single push, so the pixels and the band the renderer reads them with never disagree. Raises if the plot is not in tile mode or the range is degenerate.
- 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.In TILE mode pass the mask at the FULL image resolution: the renderer composites the mask against the OVERVIEW texture, so it is reduced to the base grid here. A mask already at the base grid is accepted unchanged. (Both are accepted because neither is wrong; what was wrong was accepting only the full-resolution one and then shipping bytes the renderer silently discards.)
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.
See
set_display_window()for the non-destructive counterpart — the one to reach for when the pixels must not move (a tiled plot, or a serialised figure being re-windowed with no Python behind it).- Return type:
None
- set_display_window(vmin=None, vmax=None)[source]#
Move the display window WITHOUT re-quantising the pixels.
The non-destructive counterpart to
set_clim(). Both change the contrast; they differ in what they do to the data behind it:set_climre-encodes the cached raw frame over the new range, so the codes always span exactly the visible band — maximum precision for what is on screen, but the pixels are re-encoded and re-sent, and the old band is gone.
set_display_windowleaves the codes and their
raw_min/raw_maxband alone and moves only the window the LUT maps through it. Nothing is re-encoded and nothing travels but two floats.
Use it when the pixels must stay put: a tiled plot, where re-quantising would re-encode the full-res frame on every drag tick (
set_climalready routes there internally), or a figure that has been serialised and is being re-windowed with no Python behind it — which is how a saved page gets a working contrast control at all.The trade is precision. Quantisation spans
[raw_min, raw_max], so a window much narrower than that band resolves in coarse steps, and one WIDER than it recovers nothing: values outside the band were saturated to 0/255 when the frame was encoded. Quantise over the range you want to be able to reach.- 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, lock_center=False)[source]#
Add a draggable circle overlay.
lock_centerpins the centre and leaves only the radius draggable — a grab on the ring body is refused and pans the plot instead. Use it when the centre is fixed by the data (a ring on a power spectrum is centred on the DC term), so it cannot be nudged off and silently corrupt every radius measured from it.
- 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)
centres (On an imshow panel the axis values sit at pixel)
the (so)
(as (image extends half a pixel beyond the first and last value)
does) (matplotlib's imshow extent)
image (on a default arange(n) axis is the whole)
tick (and the)
edge. (labelled x0 sits at the view's left)
- 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:
- add_texts(offsets, texts, name=None, *, color='#ff0000', fontsize=12, fontweight='normal', outline_color=None, outline_width=3.0, hover_edgecolors=None, labels=None, label=None, transform='data', clip_display=True)[source]#
Add text annotations at image-pixel positions.
- Parameters:
offsets (array-like, shape (N, 2)) – Anchor (top-left) positions, in the coordinate system named by
transform— image pixels for"data".name (str, optional) – Registry key. Auto-generated if omitted.
color (str or list of str, optional) – Text colour, or one per text. Default
"#ff0000".fontsize (int, optional) – Font size in pixels. Default
12.fontweight ({"normal", "bold"} or float, optional) – Font weight — a keyword or a CSS numeric weight in
[1, 1000](400 is normal, 700 bold). Default"normal".outline_color (str, optional) – Colour of a halo stroked under the text, which keeps a label legible over both light and dark regions of the image.
None(default) draws no outline.outline_width (float, optional) – Stroke width of the outline in pixels; about half of it shows outside the glyphs. Default
3.0. Ignored withoutoutline_color.hover_edgecolors (str, optional) – Colour override applied on mouse-hover.
labels (list of str, optional) – Per-annotation tooltip labels.
label (str, optional) – Collection-level tooltip label.
transform ({"data", "axes", "display"}, optional) – Coordinate system for
offsets. Default"data".clip_display (bool, optional) – Clip
"display"-transform texts to the image. DefaultTrue.
- Return type:
Examples
A bold white label with a dark halo, readable over any image:
>>> plot.add_texts([[40, 12]], ["2 Å"], fontsize=16, fontweight="bold", ... color="#ffffff", outline_color="#000000")