neu_draw.backends.pygfx

Turn a Scene into pygfx objects and draw them.

The only renderer-specific module apart from the legend and the exporters. Three primitives cover segment morphology:

drawable

pygfx

mesh

Mesh + MeshPhongMaterial

skeleton

Line + LineSegmentMaterial, fed the edge list

points

Points + PointsMarkerMaterial

LineSegmentMaterial draws a line between each consecutive pair of points, so a skeleton’s edge list is one object per body whatever its topology.

Attributes

Classes

View

A rendered scene: canvas, renderer, camera and controller, kept together.

Functions

build(scene) → pygfx.Group

Scene → a pygfx object graph. No canvas, no renderer, no draw.

display_color(drawable[, override]) → tuple

The colour a drawable's material carries: its own, times its alpha.

in_notebook() → bool

True inside an IPython kernel (a notebook), not a terminal REPL.

show(scene[, size]) → View

Render a scene and return the View. The one call a notebook needs.

Module Contents

class neu_draw.backends.pygfx.View(scene: neu_draw.scene.Scene, size: tuple[int, int] = DEFAULT_SIZE, canvas: Any = 'auto', background: tuple | None = None, pixel_ratio: float | None = None, toolbar: Any = 'auto', legend: bool | None = None, viewpoint: str | neu_draw.viewstate.ViewState | None = None)

A rendered scene: canvas, renderer, camera and controller, kept together.

Displays itself in Jupyter. Keep a reference: a garbage-collected canvas leaves a blank output cell.

center() → View

Re-fit the camera to what is visible now, and redraw. reset() returns to the opening view instead.

close() → None

Close the canvas, recording where the camera was into views["last"].

Done here, not in the toolbar, so view.close() from a cell records it too. A failure to record is ignored rather than raised.

frame() → View

Fit the camera to what is visible, honouring the scene’s Camera.

Fits a bounding sphere over the built objects’ world bounding boxes, so offsets are followed. Hidden objects are excluded (pygfx’s get_bounding_box would include them). Framing a sphere leaves slack around a long thin neurite but never crops; use Camera.zoom to tighten it.

logical_size() → tuple[int, int]

The canvas size in logical pixels, falling back to the size asked for.

A Jupyter canvas reports (1, 1) until the browser lays the widget out, so a size below a few pixels is treated as unknown.

orbit(directory: str, **kwargs) → Any

Render the camera turning about an axis, as numbered PNGs in directory.

Keywords: degrees (360), seconds (12), fps (30), axis ("up"; also right/view, data x/y/z, or an xyz vector), light ("camera" turns the lights with it, "fixed" does not), ease (linear/in-out), size, supersample (2), legend, overwrite, and encode ("auto": write an mp4 if an ffmpeg is found via ffmpeg=, $NEU_DRAW_FFMPEG or PATH), output (the mp4’s path). Returns an Orbit with the video, or the command that would make it. The view’s own camera is not moved.

refresh() → View

Re-read the scene and repaint, for a field set directly (scene.get("a").label = "Tm2") when nothing else will draw a frame. The Scene methods repaint on their own.

request_draw() → None

Ask the canvas to repaint, using the draw function already installed.

A no-op once closed, since a scene can be edited after its view is closed.

reset() → View

Back to the view this figure opened with.

Restores the opening visibility, clears highlights, and returns to the opening camera. Colours and opacity changes are kept, since they are edits to the scene.

restore_view(name: str | neu_draw.viewstate.ViewState = SAVED, *, size: bool = True) → neu_draw.viewstate.ViewState | None

Apply a saved viewpoint; returns None, not an error, if the slot is empty.

So show(scene, viewpoint="last") is safe in a fresh session. name may also be a ViewState. size restores the canvas size too, since the aspect ratio changes the framing; size=False keeps the canvas.

save(path: str, size: tuple[int, int] | None = None, *, pixel_ratio: float | None = None, legend: bool = True, groups: Any | None = None) → str

Write the figure to path: PNG, or by extension .svg / .pdf.

pixel_ratio is the PNG’s supersampling, or the mesh images’ resolution in a vector file (default 2). legend=False drops the strip. groups applies to vector files only (see save_svg()). PNGs are written without alpha.

save_pdf(path: str, **kwargs) → str

The same figure as save_svg(), as PDF, with the groups as nested layers in Acrobat’s layer panel. Illustrator opens a PDF it did not write onto a single layer, so for editing there, prefer the SVG.

save_svg(path: str, **kwargs) → str

Write the view as SVG, laid out so Illustrator keeps the named groups. Each mesh is a transparent image; points, skeletons and the legend are vectors.

groups maps a drawable to a tuple of group names to nest it under, e.g. lambda d: (d.name.split(" : ")[0],); defaults to scene.export_groups. See neu_draw.backends.vector for what is lost (occlusion between groups).

save_view(name: str = SAVED) → neu_draw.viewstate.ViewState

Record this camera into neu_draw.views, and return what was stored.

The store outlives the view, so the next figure can restore it.

set_alpha(alpha: float, *, kind: str | None = None, names: Any | None = None) → View

Opacity for every drawable of a kind ("mesh", "skeleton", "points"), or of names; what the toolbar’s sliders do. Scene.set_alpha plus the repaint.

snapshot(size: tuple[int, int] | None = None, *, pixel_ratio: float | None = None, legend: bool = True) → numpy.ndarray

Render once and return the pixels as (h, w, 4) uint8.

On a Jupyter canvas this renders a separate offscreen pass at the view’s requested size: the live framebuffer is sized by the browser and is a 2x2 placeholder until the widget is laid out.

The result is pixel_ratio times the requested size (pygfx’s supersampling, which antialiases); use pixel_ratio=1.0 for pixel-exact output. legend=False omits the strip.

camera
canvas
controller
group
legend = None
property pixel_ratio: float

Internal pixels per logical pixel; at least 2 by default.

renderer
scene
scene_data
ui = None
neu_draw.backends.pygfx.build(scene: neu_draw.scene.Scene) → pygfx.Group

Scene → a pygfx object graph. No canvas, no renderer, no draw.

Separate from show(), so what is built can be tested without a GPU.

neu_draw.backends.pygfx.display_color(drawable: Any, override: tuple | None = None) → tuple

The colour a drawable’s material carries: its own, times its alpha.

alpha multiplies the colour’s own alpha, so the two compose. override substitutes another colour (the legend’s highlight) but keeps the drawable’s alpha, so a highlighted translucent surface stays translucent.

neu_draw.backends.pygfx.in_notebook() → bool

True inside an IPython kernel (a notebook), not a terminal REPL.

neu_draw.backends.pygfx.show(scene: neu_draw.scene.Scene, size: tuple[int, int] = DEFAULT_SIZE, **kwargs) → View

Render a scene and return the View. The one call a notebook needs.

neu_draw.backends.pygfx.DEFAULT_SIZE = (900, 700)
neu_draw.backends.pygfx.EXTRA_CONTROLS