On this page

inklet API reference

Public names exported by inklet, in package order, with signatures and short descriptions. Use help(inklet.link), for example, to read the full docstring. The stable subpackages inklet.volume, inklet.selection, inklet.project and inklet.editor follow; import inklet does not import them, so import each one you use.

Numeric drawing lengths use millimetres. Many dimension arguments also accept strings such as "89mm" or "2in"; pt(9) converts 9 points to millimetres. Composition preserves child handles: combinators wrap drawings in parent nodes, so handles created before layout still resolve in the figure.

One-call charts

class Chart(*, width=None, height=None, style='scientific.modern', font_pt=None, palette=None, title=None, xlabel=None, ylabel=None, xlim=None, ylim=None, xscale='linear', yscale='linear', legend='auto', grid=None, xticks=None, yticks=None, xminor=None, yminor=None, xformat=None, yformat=None, aspect=None)

One plot: marks on shared axes, with a size and a preset.

  • line(data=None, x=None, y=None, *, color=None, name=None, markers=False, error_y=None, dash=None, linewidth=None, sort=True, gaps='break', secondary_y=None, simplify='auto', marker_size=None, marker=None, **style) -- Lines through (x, y), one per color group or per y column.
  • scatter(data=None, x=None, y=None, *, color=None, size=None, name=None, marker='circle', palette=None, error_y=None, text=None, secondary_y=None, raster=None, **style) -- Points at (x, y). A numeric color column with many values is a ramp.
  • bar(data=None, x=None, y=None, *, color=None, name=None, orient='v', stacked=False, error_y=None, labels=None, agg=None, points=False, **style) -- Bars of y at each x category; color groups side by side or stacked.
  • hist(data=None, x=None, *, color=None, bins=20, density=False, name=None, cumulative=False, **style) -- Histogram of x; one overlaid histogram per color group.
  • kde(data=None, x=None, *, color=None, fill=False, name=None, **style) -- Kernel density estimate of x, one curve per color group.
  • ecdf(data=None, x=None, *, color=None, name=None, **style) -- Empirical cumulative distribution of x, one step per color group.
  • boxplot(data=None, x=None, y=None, *, color=None, points=False, **style) -- Box plot of y in each x category; orient='h' lays the boxes across.
  • violin(data=None, x=None, y=None, *, color=None, points=False, **style) -- Violin plot of y in each x category; orient='h' lays the violins across.
  • strip(data=None, x=None, y=None, *, color=None, **style) -- Jittered points of y in each x category; orient='h' lays them across.
  • area(data=None, x=None, y=None, *, color=None, stacked=True, **style) -- Filled areas under y; groups stack unless stacked=False.
  • regression(data=None, x=None, y=None, *, color=None, method='linear', confidence=0.95, equation=False, name=None, **style) -- Points with a fitted line and its confidence band, per color group.
  • heatmap(data=None, x=None, y=None, z=None, *, palette='viridis', center=None, colorbar=True, colorbar_title=None, **style) -- A matrix of colour cells. colorbar is True, False or the bar's title.
  • survival(data=None, time=None, event=None, *, color=None, at_risk=True, pvalue=True, band='log-log', confidence=0.95, censors=True, **style) -- Kaplan-Meier survival curves: time durations and event flags, one curve per color group.
  • volcano(data=None, x=None, y=None, *, label=None, labels=None, highlight=None, q=None, **style) -- A volcano plot: x the log2 fold change, y the raw p-value, one point per row.
  • forest(data=None, label=None, estimate=None, lower=None, upper=None, *, weight=None, summary=None, left=('label',), right=('ci',), log=False, null=None, limits=None, measure='Estimate', digits=2, **style) -- A forest plot: one row per study, with its estimate and confidence interval.
  • pie(data=None, names=None, values=None, *, hole=0, labels='percent') -- A pie chart: one slice per row, sized by values, in row order.
  • lollipop(data=None, x=None, y=None, *, color=None, orient='v', **style) -- One value per category as a dot on a stem from zero: a lighter bar chart.
  • dumbbell(data=None, y=None, x=None, **style) -- Two values per category joined by a line: before and after, for instance.
  • waterfall(data=None, x=None, y=None, *, totals=(), labels=True, **style) -- Changes as bars floating on a running total: a waterfall chart.
  • slope(data=None, x=None, y=None, group=None, *, labels='both', format=None, highlight=None, **style) -- Each group's values at two or more time points, joined by a straight line.
  • labels(*, x=None, y=None, title=None, y2=None) -- Set axis titles and the chart title (all optional).
  • colorbar(**options) -- Draw the colour bar, or update the one already drawn.
  • legend(**options) -- Draw the key, or update the key already recorded.
  • twin_y(*args, **kwargs) -- Not on a quick chart: use secondary_y= for a right-hand axis.
  • twin_x(*args, **kwargs) -- Refused, for the same reason as twin_y: a quick chart has one x axis.
  • size(width=None, height=None) -- Width as 'single', 'double', 'slide' or millimetres; height in mm.
  • plot(width=None, profile=None, rotate=False, colours=None, slots=None, title=None, shared_key=False, lettered=False, cell=None) -- The PlotSpec with axes, legend and title applied, for a document cell.
  • document(rotate=frozenset(), below=frozenset()) -- A Document holding this chart, sized and styled; add cells to grow it.
  • compile() -- Measure and place everything; returns a CompiledFigure.
  • report(**options) -> 'str' -- Layout and print diagnostics: overlaps, clipped text, small type.
  • save(*paths, **options) -- Save to each path; the extension picks SVG, PDF or PNG.
  • show(path=None) -- Display in a notebook, or write an SVG and print where it went.
  • to_pdf(**options) -> 'bytes'
  • to_png(**options) -> 'bytes'
  • to_svg(**options) -> 'str'

class Layout(direction, items, *, width=None, style=None, letters=True, columns=None, palette=None, font_pt=None, grid=None)

Charts side by side (a | b) or stacked (a / b), with panel letters.

  • options(**settings) -- Set this layout's options and return it: (a | b).options(style='scientific.nature', palette='okabe-ito', font_pt=8).
  • charts()
  • document(rotate=frozenset(), below=frozenset()) -- A Document with one lettered cell per chart.
  • hline(y, *, data=None, **options) -- A horizontal reference line in every panel, or a value per facet; returns the layout.
  • vline(x, *, data=None, **options) -- A vertical reference line in every panel, or a value per facet; returns the layout.
  • compile() -- Measure and place everything; returns a CompiledFigure.
  • report(**options) -> 'str' -- Layout and print diagnostics: overlaps, clipped text, small type.
  • save(*paths, **options) -- Save to each path; the extension picks SVG, PDF or PNG.
  • show(path=None) -- Display in a notebook, or write an SVG and print where it went.
  • to_pdf(**options) -> 'bytes'
  • to_png(**options) -> 'bytes'
  • to_svg(**options) -> 'str'

class LayoutWarning

A saved chart has layout problems; the message is its lint report.

chart(**options) -> 'Chart'

An empty chart to add marks to: inklet.chart(title='...').line(...).

line(data=None, *args, **options)

Lines through (x, y), one per color group or per y column.

scatter(data=None, *args, **options)

Points at (x, y). A numeric color column with many values is a ramp.

bar(data=None, *args, **options)

Bars of y at each x category; color groups side by side or stacked.

hist(data=None, *args, **options)

Histogram of x; one overlaid histogram per color group.

boxplot(data=None, *args, **options)

Box plot of y in each x category; orient='h' lays the boxes across.

violin(data=None, *args, **options)

Violin plot of y in each x category; orient='h' lays the violins across.

strip(data=None, *args, **options)

Jittered points of y in each x category; orient='h' lays them across.

kde(data=None, *args, **options)

Kernel density estimate of x, one curve per color group.

ecdf(data=None, *args, **options)

Empirical cumulative distribution of x, one step per color group.

area(data=None, *args, **options)

Filled areas under y; groups stack unless stacked=False.

heatmap(data=None, *args, **options)

A matrix of colour cells. colorbar is True, False or the bar's title.

regression(data=None, *args, **options)

Points with a fitted line and its confidence band, per color group.

survival(data=None, *args, **options)

Kaplan-Meier survival curves: time durations and event flags, one curve per color group.

volcano(data=None, *args, **options)

A volcano plot: x the log2 fold change, y the raw p-value, one point per row.

pie(data=None, *args, **options)

A pie chart: one slice per row, sized by values, in row order.

lollipop(data=None, *args, **options)

One value per category as a dot on a stem from zero: a lighter bar chart.

dumbbell(data=None, *args, **options)

Two values per category joined by a line: before and after, for instance.

waterfall(data=None, *args, **options)

Changes as bars floating on a running total: a waterfall chart.

slope(data=None, *args, **options)

Each group's values at two or more time points, joined by a straight line.

from_matplotlib(figure, *, width=None, style='scientific.modern', palette=None, keep_colors=False, letters=True)

Convert a matplotlib Figure (or one Axes) into an inklet chart or layout.

class MatplotlibWarning

Parts of a matplotlib figure that the bridge did not convert.

rendering_capabilities()

Declared format support; no renderer is selected implicitly.

class RenderScene(root: 'SceneNode', bbox: 'Rect', stats: 'Mapping', changes: 'tuple[SceneChange, ...]', _nodes: 'Mapping', _resources: 'Mapping', _images: 'Mapping', _fonts: 'Mapping') -> None

A compiled native scene shared by SVG, PDF and PNG exports.

  • walk()
  • validate_fonts()
  • font_manifest() -- Return the captured font inventory without rereading font files.
  • sources_current() -- Check external inputs when a document considers reusing a snapshot.
  • to_svg(**options)
  • to_pdf(**options)
  • to_png(**options)
  • to_html(*, title='Inklet figure', backend='auto', **options) -- Offline HTML viewer; WebGL2 filled markers, Canvas fallback, SVG art.
  • damage_bounds(previous: 'RenderScene') -- Conservative old/new ink union for changed placements, in page mm.

compile_scene(root: 'Diagram | RenderScene', *, previous: 'RenderScene | None' = None) -> 'RenderScene'

Resolve a drawing for all native backends, reusing an optional revision.

class FontEmbeddingWarning

A PDF asked for live text drew some of it as outlines.

class Suite(name: 'str', *, base: 'object' = 'scientific.nature', font: 'str' = 'Helvetica, Arial, Liberation Sans, sans-serif', allowed_fonts: 'tuple[str, ...] | None' = None, ink: 'str | None' = None, paper: 'str' = '#ffffff', type: 'TypeScale' = <factory>, lines: 'LineWeights' = <factory>, markers: 'MarkerStyle' = <factory>, letters: 'LetterStyle' = <factory>, text: 'TextRules' = <factory>, palettes: 'Mapping[str, object]' = <factory>, ramps: 'Mapping[str, object]' = <factory>, widths: 'Mapping[str, float]' = <factory>, export: 'Export' = <factory>, lint: 'Mapping[str, object]' = <factory>) -> None

A figure set's house style: fonts, type, line weights, markers, colours, letters, text rules, widths, export and lint. Build one with suite().

  • customize(**changes) -> "'Suite'" -- A copy with fields replaced. A dict for one of the nested style fields (type, lines, markers, letters, text, export) merges into it: customize(lines={"data": 0.5}) keeps fit and axis. palettes, ramps, widths and lint are replaced whole.
  • font_families(*, allowed: 'bool' = False) -> 'tuple[str, ...]' -- The families in font (or allowed_fonts), generic names dropped.
  • fonts() -> 'dict[str, dict]' -- How each face the suite sets resolves on this machine: file, family, and whether a PDF can embed it as live text.
  • size(role: 'str') -> 'float' -- A type size in mm: 'tick', 'label', 'key', 'note' or 'letter'.
  • stroke(tier: 'str' = 'data') -> 'float' -- A line weight in mm by tier name ('data', 'fit', 'axis' or an extra).
  • width(name: 'str | float' = 'double') -> 'float' -- A named page width in mm ('single', 'double', ...), or a number as is.
  • palette(name: 'str') -- A categorical palette as given: {key: colour} or a tuple.
  • color(key: 'str', palette: 'str | None' = None) -> 'str' -- The colour of key: from palette, or the first palette that has it; a colour string is returned unchanged.
  • ramp(name: 'str') -> 'Callable[[float], str]' -- A sequential map as a function of t in [0, 1]. Ordinal dict ramps are sampled along their keys in order.
  • stops(name: 'str') -> 'dict' -- An ordinal ramp's fixed {key: colour} stops.
  • text_color(color: 'str') -> 'str' -- color deepened along its own lightness until text in it reaches text.label_contrast on the paper; hue is kept. A grey becomes ink.
  • mark_color(color: 'str') -> 'str' -- A marker colour: color (a palette key or a colour) deepened to markers.min_contrast on the paper, or unchanged at 1.0.
  • line(color: 'str', tier: 'str' = 'data', **style) -> 'dict' -- Panel.line keywords: the colour (a palette key or a colour) and the tier's weight.
  • mark(color: 'str', *, hollow: 'bool' = False, size: 'float | None' = None, **style) -> 'dict' -- Panel.scatter keywords for the house marker: filled without an outline, or open as a ring in the series colour.
  • marker(shape: 'str', color: 'str', *, hollow: 'bool' = False, size: 'float | None' = None) -> 'Diagram' -- One placed or key marker in the house style (see mark).
  • panel(width: 'float', height: 'float', **kwargs) -- inklet.panel built under this suite's theme.
  • axes(p, x=None, y=None, **kwargs) -- Panel.axes at the suite's tick and label sizes and axis weight.
  • label(text: 'str', *, role: 'str' = 'note', color: 'str | None' = None, **kwargs) -> 'Diagram' -- A text node at a role's size, never bold, in ink or the deepened colour of color.
  • end_labels(p, labels: 'Mapping[str, tuple[float, float]]', *, colors: 'Mapping[str, str] | None' = None, gap: 'float' = 0.4, dx: 'float' = 1.0, anchor: 'str' = 'w', role: 'str' = 'note') -- Direct series labels at line ends, spread so none overlap.
  • mosaic(layout, panels, *, height: 'float', width: 'str | float' = 'double', **kwargs) -> 'Diagram' -- inklet.panel_mosaic with the suite's letters (size, gap, case).
  • letter(text: 'str') -> 'Diagram' -- A panel letter on its own, for hand-built layouts: the suite's size, bold, baseline-aligned like the mosaic's (header_text).
  • figure(width: 'str | float' = 'double', **kwargs) -- inklet.figure on the suite's theme and paper, at a named width.
  • document(width: 'str | float' = 'double', **kwargs) -- The suite preset's live Document at a named width: the suite's font, type sizes and paper. Its panel letters follow the base preset's letter style, not letters.
  • lint_rules() -- The suite's house rules as HouseRules for lint(house=...).
  • lint_options() -> 'dict' -- The lint() keywords check uses: the base preset's limits, the suite's fonts, paper and house rules, then lint.
  • check(figure, **kwargs) -- Lint diagnostics for a figure under the suite's limits and house rules. Takes a Figure, compiled Document, Document or Diagram.
  • page(item, width=None) -- item as something that saves and lints: a Figure or compiled Document passes through, a Document is compiled, and a Diagram or Panel is put on a suite figure as wide as it (or width).
  • save(item, name: 'str', *, out: 'str | Path' = '.', width=None, report: 'bool' = False) -> "'SaveResult'" -- Write out/name.{formats} and lint them. Returns a SaveResult.
  • build(figures: 'Mapping[str, object] | Iterable[tuple[str, object]]', *, out: 'str | Path', only: 'Sequence[str] | None' = None, inputs: 'Mapping[str, Sequence] | None' = None, depends: 'Sequence[str | Path]' = (), force: 'bool' = False, isolate: 'bool' = True, report: 'bool' = True) -> "'BuildReport'" -- Build a set of figures, skip the unchanged ones, lint them all.

suite(name: 'str', **options) -> 'Suite'

A house style for a figure set; see Suite for every field. Nested fields take dicts: suite("lab", lines={"data": 0.6, "fit": 0.75}).

current_suite() -> 'Suite | None'

The suite of the innermost with suite: block, or None.

blend(node, mode='multiply')

Blend an isolated group with the artwork behind it, natively in SVG/PDF.

mask(content, stencil, *, mode='luminance', dpi=300)

Apply a same-coordinate stencil as a recorded raster layer.

class LinearGradient(stops: tuple, start: tuple = (0.0, 0.0), end: tuple = (1.0, 0.0)) -> None

Opaque colour stops from start to end in fractions of the shape bounds.

class RadialGradient(stops: tuple, center: tuple = (0.5, 0.5), radius: float = 0.5) -> None

Concentric opaque gradient in shape-bound fractions; circles become ellipses on rectangular bounds.

class Hatch(color: str = '#666666', spacing: float = 2.0, stroke: float = 0.2, angle: float = 45.0, background: str | None = None) -> None

Parallel vector strokes with spacing/width in local millimetres.

paint(node, brush)

Fill a shape or shape group with a vector gradient or hatch; retain text and authored strokes.

class SceneRender(diagram: inklet.core.diagram.Diagram, metadata: dict, cache_hit: bool, passes: object = <factory>) -> None

A rendered snapshot, its provenance and whether cached pixels were reused.

  • project(point, *, depth_bias=0.001) -- Project a world point into centred millimetres; test visibility with depth.
  • path3d(points, *, hidden='omit', depth_bias=0.001, step_px=1.0, max_samples=200000, **style) -- Create an aligned vector path with occluded sections omitted, dashed or shown.
  • annotate3d(point, text, *, side='n', clear=2.0, hidden='omit', depth_bias=0.001, leader=True, head='none', size=None, avoid=(), leader_style=None, **text_style) -- Label a world point; omit hidden targets or dash their screen-space leader.
  • dimension3d(a, b, text=None, *, scale=1.0, unit='scene units', precision=3, offset=0.0, hidden='omit', depth_bias=0.001, size=None, tick=1.2, witness=True, plate=True, **style) -- Dimension projected endpoints, labelled with their true 3D distance.
  • arrow3d(a, b, *, hidden='omit', depth_bias=0.001, head='triangle', head_size=1.6, step_px=1.0, max_samples=200000, **style) -- Depth-test a world-space shaft with a constant page-size arrowhead.
  • angle3d(a, vertex, b, text=None, *, radius=None, precision=1, hidden='omit', depth_bias=0.001, side='n', clear=2.0, size=None, step_px=1.0, max_samples=200000, **style) -- Measure the 3D angle a-vertex-b and project an arc in its world plane.
  • object_mask(*names) -- Return an aligned stencil for named objects; request object_id first.

class ScenePass(name: str, pixels: tuple[int, int], channels: int, width_mm: float, height_mm: float, data: bytes) -> None

Immutable little-endian float32 pixels, in top-left row order.

  • value(x, y) -- Read one pixel without NumPy; normals return an XYZ tuple.
  • to_numpy() -- Return a read-only H×W or H×W×3 NumPy view; requires inklet[images].
  • save(path) -- Save numeric data as .npy without losing precision or changing axes.
  • to_diagram(*, value_range=None) -- Visualize a pass with transparent background; requires inklet[images].
  • object_mask(ids) -- Make a white alpha stencil for object IDs, aligned with the scene.

class ProjectedPoint(point: inklet.core.geom.Vec2, depth: float, in_frame: bool, visible: bool | None) -> None

A world point in centred figure millimetres, with camera visibility.

class BlendSceneSpec(path: object, options: dict = <factory>, _dependencies: tuple = ()) -> None

Deferred scene rendering with file and live-data cache invalidation.

  • signature(trail=())
  • render(context, width=None, height=None)

render_blend(path, *, width, height=None, camera=None, scene=None, frame=None, dpi=None, engine=None, samples=None, seed=0, transparent=True, landmarks=None, objects=None, collections=None, bindings=None, assets=(), cache=None, blender=None, timeout=900, threads=4, max_pixels=40000000, view_layer=None, passes=(), quality=None, denoise=None, noise_threshold=None, style='authored', device='AUTO', devices=None, fallback='cpu', progress=None, cancel=None)

Render an existing .blend file without modifying it.

blend_scene(path, **options)

A complete Blender scene as a Diagram; see render_blend for options.

blend_scene_spec(path, **options)

Create a live scene panel that responds to asset and data changes.

scene_templates()

Return a fresh JSON-compatible catalogue; Blender is not required.

create_scene(template, path, *, parameters=None, blender=None, overwrite=False, timeout=90, progress=None, cancel=None)

Create an editable .blend from laboratory, product or architecture.

class RenderQuality(name: str, dpi: float, samples: int, denoise: bool, noise_threshold: float) -> None

Physical resolution and Cycles sampling settings for scene renders.

render_quality(name='preview', **overrides)

Get immutable draft, preview or final settings, with validated overrides.

inspect_blend(path, *, blender=None, timeout=30)

List authored scenes, cameras, view layers, objects and materials without rendering.

render_devices(*, blender=None, timeout=30, refresh=False)

List Cycles backends, device IDs and discovery errors without rendering.

class RenderQueue(max_workers=2, *, max_gpu_jobs=1)

Schedule scene renders with worker and GPU concurrency limits.

  • submit(path, **options) -- Queue render_blend arguments and return a cancellable RenderJob.
  • shutdown(*, wait=True, cancel=False) -- Stop accepting jobs; optionally cancel pending and running renders.

class RenderJob()

A queued or running scene render with cancellation and its latest update.

  • cancel() -- Request cancellation, including for running Blender processes.
  • done()
  • result(timeout=None) -- Wait for a SceneRender; timeout only limits this wait, not the render.

class RenderProgress(phase: str, message: str, fraction: float | None = None) -> None

One render update; fraction is optional and refers to the current phase.

class RenderCancelled

Rendering was cancelled before a complete snapshot was committed.

to_png(root, *, dpi=150, **options)

Return PNG bytes at physical DPI, without Chrome or a display server.

save_png(root, path, **options)

Save a Diagram as PNG; see to_png for physical DPI and backgrounds.

rasterize(node, *, dpi=300, reason='explicit raster layer')

Freeze one expensive layer as pixels, preserving its size and anchors.

Live documents

class PublicationProfile(name: str, width: float, font_pt: float = 8, small_font_pt: float = 7, stroke_mm: float = 0.18, min_font_pt: float = 6, min_stroke_mm: float = 0.1, min_dpi: float = 300, dpi: float = 300, text: str = 'embed', base_theme: inklet.themes.theme.Theme | str = 'nature', title_font_pt: float | None = None, max_font_pt: float | None = None, max_height_mm: float | None = None, letter_font_pt: float | None = None, max_letter_pt: float | None = None, expected_fonts: tuple[str, ...] | None = None) -> None

An editable set of physical page, typography, stroke and export defaults.

  • document(**options) -- Create a document with this profile's theme, checks and export defaults.

publication(name='double-column', **options)

Choose single-column (89 mm), double-column (183 mm), or slide (254 mm).

class FigureFormat(name: 'str', width: 'float', height: 'float | None' = None) -> None

Physical page dimensions in millimetres; None height fits the content.

class PlotDefaults(grid: 'str' = 'none', legend_side: 'str' = 'bottom', tick_count: 'int' = 5, bar_fill: 'str' = 'neutral', axes: 'str' = 'open') -> None

Defaults for live plot recipes; explicit recipe options take precedence.

class GuidelineSource(title: 'str', url: 'str', reviewed_on: 'str | None', status: 'str', scope: 'str') -> None

Journal guidance provenance, distinguishing reviewed and unverified sources.

class Preset(name: 'str', description: 'str', format: 'FigureFormat', publication: 'PublicationProfile', plot: 'PlotDefaults' = PlotDefaults(grid='none', legend_side='bottom', tick_count=5, bar_fill='neutral', axes='open'), margin: 'float' = 4, gap: 'float' = 6, letter_style: 'str' = 'bold-lower', sources: 'tuple[GuidelineSource, ...]' = (), letter_pad: 'float | None' = None) -> None

An immutable figure style, format, plot policy and publication profile.

  • customize(**options) -> 'Preset' -- Return a preset with explicit overrides; dimensions use millimetres.
  • document(**options) -- Create a live document, retaining explicit page overrides on preset switches.
  • as_dict() -- Return a JSON-compatible record of resolved settings and source guidance.

preset(name='scientific.general', *, format=None, **overrides) -> 'Preset'

Choose a scientific, educational or marketing preset and physical format.

preset_names(family=None) -> 'tuple[str, ...]'

List built-in presets, optionally restricted to one family.

format_names() -> 'tuple[str, ...]'

List built-in physical formats accepted by preset().

subfigure(*, width=180, height=None, columns=1, margin=0, gap=6, row_gap=None, share_plot_margins=False, stretch=True)

Create a nested grid. Children inherit the enclosing document theme.

A figure assembled from named children and measured expressions.

  • measure(name, dimension='width') -- Reference a child's measured width or height, in composition units.
  • point(name, anchor='center') -- Reference a placed child's compass point or registered port.
  • add(name, item, *, x=0, y=0, anchor=None, width=None, height=None, scale=1)
  • replace(name, item) -- Replace a child while preserving its placement and dependent references.
  • slot(name, **placement) -- Declare a required content input with the same placement options as add().
  • copy() -- Copy nested compositions, plots, modules and component instructions.
  • instantiate(**items) -- Create an independent recipe, filling required slots and replacing defaults.
  • configure(*, width=None, height=None, unit=None, fit_top=None) -- Atomically update authored page dimensions or coordinate units.
  • place(name, **placement) -- Edit a child's placement without replacing its content or named links.
  • layout_overrides(reference) -- Capture changed layout, named labels and supported styles against a reference.
  • with_layout_overrides(value, *, missing='error') -- Return an independent edited recipe and a reconciliation report.
  • port(name, target) -- Expose a child's name:anchor as a reusable composition attachment point.
  • constrain(value, *, minimum=0, message='composition needs more space') -- Require an expression to meet a minimum; fail before drawing.
  • link(source, target, **options) -- Route a branch or return between named children (name:port).
  • annotate(target, text, **options) -- Place a measured callout; a unique name enables saved label editing.
  • signature(trail=())
  • render(context, width=None, height=None)

class LayoutValue(operation: 'str', args: 'tuple') -> None

A scalar layout expression evaluated after its dependencies are measured.

composition(width, height, *, unit=1, fit_top=False)

Create a measured composition; see Composition for coordinate semantics.

class ModuleSpec(label: object, min_width: float = 20, min_height: float = 12, pad: float = 3, max_height: float | None = None, ports: dict = <factory>, text_style: dict = <factory>, box_style: dict = <factory>, label_offset: tuple = (0, 0), max_width: float | None = None) -> None

A label-sized module. Port coordinates are fractions of its box.

  • configure(label=None, **options)
  • signature(trail=())
  • render(context, width=None, height=None)

module(label, **options)

Create a measured module with fractional ports.

A physical page containing named, live figure definitions.

  • add(name, item, *, row=None, column=0, rowspan=1, colspan=1, min_width=None, min_height=None, align='center', grow=True) -- Place a named cell; align fixed artwork by a compass point.
  • configure(**options) -- Validate page changes together before applying them.
  • use_preset(selected, *, format=None, keep_overrides=True, **options) -- Switch presets and remeasure live content, preserving explicit page options.
  • replace(name, item) -- Replace a cell definition while retaining its layout constraints.
  • link(source, target, **kwargs) -- Connect named cells, optionally cell:anchor, after layout.
  • letters(names=None, *, start='a', anchor='content', **options) -- Measure panel letters with the cells, reserving room before placement.
  • label(*, x: 'str | None' = None, y: 'str | None' = None, **unknown) -- Name the grid once: x under its bottom row, y beside its left column.
  • signature(trail=())
  • render(context, width=None, height=None)
  • compile() -- Measure dependencies and return a cached CompiledFigure snapshot.
  • export(directory, **kwargs)
  • save(*paths, **kwargs)

class CompiledFigure(_state: 'CompiledState', cells: 'Mapping', diagnostics: 'tuple', metadata: 'Mapping', stats: 'Mapping') -> None

A resolved snapshot; later authoring changes cannot alter its exports.

  • build() -- Return the retained drawing and read-only resolved placements.
  • lint(**kwargs)
  • report(**kwargs)
  • layout_report() -> 'str' -- Which cells set each row's height, unused space per cell, and the alternative kept for each choose() cell.
  • to_svg(*, text=None, **kwargs)
  • to_pdf(*, text=None, **kwargs)
  • to_png(*, dpi=None, **kwargs)
  • save(*paths, **kwargs)
  • export(directory, **kwargs)

class LayoutError

A document cannot satisfy its declared physical layout constraints.

document(*, width=180, height=None, columns=1, margin=4, gap=6, row_gap=None, theme='nature', publication=None, share_plot_margins=False, pack=False)

Create a live document; optionally share plot furniture across the grid.

class PlotSpec(width: 'float' = 40, height: 'float' = 30, options: 'dict' = <factory>, _steps: 'list' = <factory>, _findings: 'list' = <factory>, _width_given: 'bool' = False) -> None

A live plot recipe. Construct with plot_spec().

  • copy() -- Copy instructions and nested plots, retaining explicit live dependencies.
  • extend(other, *, prefix=None) -- Append an independent copy of another plot's recorded instructions.
  • style(key, **options) -- Merge keyword options into a named instruction without replacing data.
  • replace(key, *args, **kwargs) -- Replace arguments of an instruction recorded with key=....
  • remove(key)
  • configure(*, width=None, height=None, **options) -- Validate physical dimensions together before applying configuration.
  • annotate(x, y, text, *, avoid_marks=True, key=None, **options) -- Place a callout after marks, insets and brackets have been measured.
  • group_labels(categories, *, key=None, **kwargs)
  • series(series, *, kind='line', uncertainty=True, key=None, **style) -- Draw a shared Series definition, including its name and uncertainty.
  • twin_y(scale=None, **options) -- Record a second y-axis; returned instructions share the parent area.
  • twin_x(scale=None, **options) -- Record a second x-axis; returned instructions share the parent area.
  • signature(trail=())
  • render(context, width=None, height=None)

class ComponentSpec(factory: 'object', args: 'tuple' = (), kwargs: 'dict' = <factory>, responsive: 'bool' = False) -> None

A diagram factory with explicit, versioned arguments and dependencies.

  • configure(*args, **kwargs)
  • signature(trail=())
  • render(context, width=None, height=None)

class Choice(options: 'tuple', names: 'tuple') -> None

Alternative definitions of one cell. Construct with choose().

  • signature(trail=())
  • render(context, width=None, height=None)

plot_spec(width=None, height=30, **options)

Defer Panel drawing instructions until a document is compiled.

component(factory, *args, responsive=False, **kwargs)

Rebuild a component under its document theme when its arguments change.

choose(*options, **named)

Offer a document cell several layouts; the page keeps the shortest.

class Dataset(columns, *, units=None, source: 'Source | None' = None, name='data')

An equal-length column table with explicit updates and a revision number.

  • update(**columns)
  • column(name)
  • points(x, y)

class DataRef(table: 'Dataset', names: 'tuple') -> None

DataRef(table: 'Dataset', names: 'tuple')

  • evaluate()

class Source(citation: 'str', method: 'str' = 'measured', path: 'str | None' = None) -> None

Data origin and construction method carried into an export manifest.

class Series(name: 'str', x: 'object', y: 'object', color: 'str', lower: 'object' = None, upper: 'object' = None) -> None

Shared name, colour, values and optional absolute uncertainty bounds.

  • draw(panel, *, kind='line', uncertainty=True, **style)

class SharedScale(columns: 'tuple', padding: 'float' = 0.05, include_zero: 'bool' = False, kind: 'str' = 'linear') -> None

One live numeric domain computed from all supplied column references.

  • evaluate()

dataset(columns, *, units=None, source=None, name='data')

Create a versioned Dataset with units and an optional source record.

read_csv(path, *, types, units=None, name='data', citation=None, method='measured', encoding='utf-8-sig', delimiter=',')

Read a local CSV into a Dataset with explicit types and source provenance.

shared_scale(*columns, padding=0.05, include_zero=False, kind='linear')

Share a live numeric domain across plots, rejecting incompatible units.

class CategoryEncoding(definition: 'object', selected: 'tuple | None' = None) -> None

A live selection of a CategorySet shared by marks, axes and legends.

  • select(keys)
  • evaluate()
  • scale(*, reverse=False, gap=1.0, padding=0.1, outer=None)

class FileRef(path: 'object') -> None

An explicit file dependency for component factories such as asset.

  • evaluate()

class DerivedData(factory: 'object', inputs: 'tuple') -> None

A deterministic transformation of explicit live inputs.

  • evaluate()

derive(factory, *inputs)

Derive live values, such as filtered rows or stacked series, from inputs.

Authoring

text(content: 'str', *, size: 'float | str | None' = None, font: 'str | None' = None, weight: 'str | None' = None, align: 'str' = 'center', width: 'float | str | None' = None, line_height: 'float | None' = None, features: 'dict[str, bool | int] | None' = None, markup: 'bool' = True, angle: 'float' = 0.0, kind: 'str' = 'text', bounds: 'str' = 'font', **style) -> 'Diagram'

Return shaped text as a diagram with bounds based on its ink extent.

label(content: 'str', **kwargs) -> 'Diagram'

Text for annotations, using the theme's small font size by default.

title(content: 'str', **kwargs) -> 'Diagram'

text at the theme's large size, tagged as a title.

box(content: 'str | Diagram | None' = None, *, pad: 'float | str | None' = None, radius: 'float | str | None' = None, shape_: 'str' = 'rect', width: 'float | str | None' = None, height: 'float | str | None' = None, **style) -> 'Diagram'

A labelled container that sizes itself to what is inside it.

circle(content: 'str | Diagram | None' = None, **kwargs) -> 'Diagram'

box with an elliptical outline, taking the same keywords.

asset(path: 'str | Path', *, width: 'float | str | None' = None, height: 'float | str | None' = None, cutout: 'Cutout | str | bool | None' = 'auto', cutout_tolerance: 'float | None' = None, lineart: 'LineArt | str | bool | None' = False, palette: 'Harmonize | Sequence[str] | float | bool | None' = None, palette_strength: 'float | None' = None, anchors: 'Mapping[str, Sequence[float]] | None' = None, outline: 'bool' = True, outline_tolerance: 'float' = 0.35, outline_max_points: 'int' = 96, outline_resolution: 'int' = 512, license: 'str | None' = None, attribution: 'str | None' = None, source_url: 'str | None' = None, sidecar: 'bool' = True, cache_dir: 'str | Path | None' = None, name: 'str | None' = None) -> 'Diagram'

Place an image as a diagram that knows its own silhouette.

escape_markup(text: 'str') -> 'str'

text with every markup character made literal.

strip_markup(text: 'str') -> 'str'

Return text with its markup removed.

text_on_path(content: 'str | Diagram', along, **kwargs) -> 'Diagram'

Set a line of text along a curve, one shaping cluster per station.

text_on_arc(content: 'str | Diagram', radius: 'float', angle: 'float', **kwargs) -> 'Diagram'

Set a line of text around a circle, centred on the bearing angle.

baseline(source: 'object' = (), *, curves: 'Sequence[Sequence[object]] | None' = None, closed: 'bool' = False) -> 'Baseline'

A Baseline from whatever describes the curve.

baseline_arc(radius: 'float', start: 'float', end: 'float', centre: 'object' = None, *, center: 'object' = None) -> 'Baseline'

The circular arc from bearing start to bearing end, exactly.

class Baseline(points: 'tuple[Vec2, ...]', tangents: 'tuple[Vec2, ...]', lengths: 'tuple[float, ...]') -> None

A curve to set type along, resampled as one arclength axis.

  • at(station: 'float') -> 'tuple[Vec2, Vec2]' -- The point and unit tangent station mm along, from the start.
  • offset(distance: 'float') -> 'Baseline' -- The parallel curve distance mm to the right of the direction of travel -- which for text set side="above" is below the letters.
  • reversed() -> 'Baseline' -- The same curve walked the other way: stations measured from the far end, tangents turned round. Setting a run on it is what puts the type on the other side of the line without mirroring a single glyph.

Drawing

arrow(points, *, smooth: 'float' = 0.5, head: 'str' = 'triangle', head_length: 'float | str' = 2.0, head_width: 'float | str | None' = None, both: 'bool' = False, color: 'str | None' = None, stroke_width: 'float | str' = 0.35, **style) -> 'Diagram'

Draw an arrow through waypoints, or along an existing single open path.

tag(content: 'str | Diagram', *, size=None, font=None, weight=None, color: 'str | None' = None, fill: 'str | None' = None, pad=(0.9, 0.35), radius=0.3, stroke='none', stroke_width=0.15, markup: 'bool' = True) -> 'Diagram'

A label plate sized from shaped text, with no font stretching.

path(points: 'Iterable[Point]' = (), *, closed: 'bool' = False, curves: 'Sequence[Sequence[Point]] | None' = None, holes: 'Sequence[Iterable[Point]]' = (), filled: 'bool | None' = None, fill_rule: 'str' = 'nonzero', kind: 'str' = 'path', **style) -> 'Diagram'

One subpath, exactly as given -- plus any rings cut out of it.

polyline(points: 'Iterable[Point]', **kwargs) -> 'Diagram'

An open run of straight segments.

polygon(points: 'Iterable[Point]', **kwargs) -> 'Diagram'

A closed run of straight segments, fillable.

curve(points: 'Iterable[Point]', *, smooth: 'float' = 0.5, closed: 'bool' = False, **kwargs) -> 'Diagram'

Return a Catmull-Rom spline through every point as cubic Bézier segments.

arc(radius: 'float | str', start: 'float', end: 'float', *, closed: 'bool' = False, kind: 'str' = 'path', **style) -> 'Diagram'

Approximate a circular arc from start to end degrees with cubic Bézier segments.

sector(radius: 'float | str', start: 'float', end: 'float', *, inner: 'float | str' = 0.0, kind: 'str' = 'path', **style) -> 'Diagram'

The wedge between two angles: a pie slice, or a ring segment with inner set. Filled by default, since a sector is an area.

marker(kind: 'str' = 'circle', size: 'float | str | None' = None, **style) -> 'Diagram'

One data glyph, centred on its own origin so place() lands it on the point it stands for.

place(items: 'Iterable[tuple[Point, Diagram] | Diagram]', *, anchor: 'str' = 'center', origin: 'Point | None' = None, kind: 'str' = 'place', **style) -> 'Diagram'

Put children at explicit coordinates, in millimetres.

window(items: 'Diagram | Iterable[Diagram]', region: 'Rect | Sequence[Point]', *, kind: 'str' = 'window', **style) -> 'Diagram'

Crop painted content to a fixed convex window, in local millimetres.

clip(items: 'Diagram | Iterable[Diagram]', region: 'Rect | Sequence[Point]', *, kind: 'str' = 'clip', strict: 'bool' = False, **style) -> 'Diagram'

Cut items down to region, in the coordinate frame you pass it in.

encoded(kind: 'str' = 'path') -> 'str'

Mark a kind as one whose stroke width is data rather than design.

drawn(items: 'Diagram | Iterable[Diagram]', *, kind: 'str' = 'place', **style) -> 'Diagram'

Absolute-coordinate geometry, back in the coordinates it was drawn in.

as_drawn(node: 'Diagram') -> 'Diagram'

Put a drawn node back at the coordinates it was drawn in.

placed_anchor(item: 'Diagram', anchor: 'str' = 'center') -> 'Vec2'

An item's named anchor, in the coordinates of whoever holds it.

plot_area(node: 'Diagram') -> 'Rect | None'

Where a panel keeps its data, or None for a node that is not one.

Annotating

annotate(target: 'Diagram | AnchorRef', text: 'str | Diagram', *, side: 'str' = 'n', clear: 'float | str' = 2.0, leader: 'bool' = True, avoid: 'Sequence[Diagram | Rect]' = (), within: 'Diagram | None' = None, size: 'float | str | None' = None, align: 'str' = 'center', name: 'str | None' = None, head: 'str' = 'none', shoulder: 'float | str | None' = None, through: 'Sequence[Diagram]' = (), leader_style: 'dict | None' = None, search: 'bool' = True, keep: 'Rect | None' = None, **style) -> 'Diagram'

Put text outside target, clear millimetres off it, with a leader.

annotation_side(node: 'Diagram | str') -> 'str | None'

Which side an annotate label actually landed on.

bracket(a, b, *, side: 'str' = 'n', text: 'str | Diagram | None' = None, tick: 'float | str' = 1.0, clear: 'float | str' = 0.0, pad: 'float | str | None' = None, size: 'float | str | None' = None, within: 'Diagram | None' = None, kind: 'str' = 'bracket', **style) -> 'Diagram'

The grouping bracket over two things, with text centred on it.

dimension(a, b, text: 'str | Diagram | None' = None, *, offset: 'float | str' = 0.0, tick: 'float | str' = 1.2, witness: 'bool' = True, plate: 'bool' = True, size: 'float | str | None' = None, within: 'Diagram | None' = None, kind: 'str' = 'dimension', **style) -> 'Diagram'

A dimension line from a to b, ticked at both ends and labelled.

scalebar(length: 'float', text: 'str | Diagram | None' = None, *, panel=None, over: 'Diagram | None' = None, corner: 'str' = 'sw', pad: 'float | str | None' = None, thickness: 'float | str | None' = None, plate: 'bool | None' = None, axis: 'str' = 'x', ink: 'str | None' = None, kind: 'str' = 'scalebar', **style) -> 'Diagram'

A scale bar, with its length written under it.

letters(items: 'Iterable', *, start: 'str' = 'a', style: 'str' = 'bold-lower', corner: 'str' = 'nw', pad: 'float | str | None' = None, inside: 'bool' = False, size: 'float | str | None' = None, **text_style) -> 'list[Diagram]'

a, b, c on the corner of each item, as diagrams you can stack.

label_slot(target: 'Diagram | AnchorRef', body: 'Diagram', *, side: 'str' = 'n', clear: 'float | str' = 2.0, within: 'Diagram | None' = None, placements: 'Mapping[str, Placement] | None' = None) -> 'Rect'

The rectangle annotate would put this label in, without building it.

label_specs(node: 'Diagram') -> 'tuple[LabelSpec, ...]'

Every annotate request recorded anywhere in node, in call order.

label_column(labels, targets, *, x, bounds, side='right', gap=1, leader_color='#777777', leader_width=0.2) -> 'Diagram'

Place measured label Diagrams beside points without vertical overlap.

place_labels(art: 'Diagram', *, sides: 'Sequence[str]' = ('n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'), radii: 'Sequence[float] | None' = None, weights: 'LabelWeights | None' = None, clearance: 'float | str | None' = None, method: 'str' = 'greedy') -> 'Diagram'

Re-place every annotate label in art, deciding all of them at once.

label_plan(art: 'Diagram', *, sides: 'Sequence[str]' = ('n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'), radii: 'Sequence[float] | None' = None, weights: 'LabelWeights | None' = None, clearance: 'float | str | None' = None, method: 'str' = 'greedy') -> 'tuple[LabelChoice, ...]'

What place_labels would do, without doing it.

class LabelChoice(target: 'str', side: 'str', clear: 'float', score: 'float', asked: 'str', overlap: 'float' = 0.0, crossings: 'int' = 0, length: 'float' = 0.0, unresolved: 'bool' = False) -> None

Where one label ended up, and what it cost.

class LabelWeights(overlap: 'float' = 1.0, crossing: 'float' = 4.0, length: 'float' = 0.3) -> None

What the placer is trading off, in units it can actually compare.

Scientific diagram components

database(content, *, width=None, height=None, pad=None, **style)

A labelled cylinder with input/output ports on its vertical sides.

feature_matrix(values, *, row_labels=None, column_labels=None, cell=4, ramp=None, label=None, highlight_rows=(), gap=None, **style)

A matrix with text/diagram headers and named row/column connection points.

sequence(items, *, pitch=None, gap=None, stem=0, baseline=False, **style)

A row of text or diagram symbols with item-0, ... and input/output ports.

value_table(rows, *, headers=None, font_size=3, header_size=None, font=None, pad=(1, 0.7), min_cell_width=0, min_cell_height=0, fill='white', header_fill='#eeeeee', color='#222222', stroke='#cccccc', stroke_width=0.15, formatter=<class 'str'>)

A compact numeric/text table with measured, glyph-centered cells.

Plotting

panel(width: 'float | str', height: 'float | str', *, x=None, y=None, nice: 'bool' = False, clip: 'bool' = False) -> 'Panel'

A plot area of a fixed size, with scales fitted to it.

class Panel(width: 'float', height: 'float', x: 'Scale', y: 'Scale', clip: 'bool' = False, _under: 'list[Diagram]' = <factory>, _content: 'list[Diagram]' = <factory>, _over: 'list[Diagram]' = <factory>, _title: 'tuple[Diagram, str, float] | None' = None, _built: 'Diagram | None' = None, _parent: "'Panel | None'" = None, _scale_domain: 'Scale | None' = None, _ramp: 'object | None' = None, _matrix: 'bool' = False, _brackets: 'list[Diagram]' = <factory>, _keys: 'list[SeriesKey]' = <factory>, _spans: 'list' = <factory>, _insets: 'list' = <factory>, _inset_state: 'tuple' = (), _deferred: 'dict' = <factory>, _sizes: 'object | None' = None, _widths: 'object | None' = None, _ternary: 'object | None' = None, _survival: 'list' = <factory>, _side_stacks: 'dict' = <factory>, _key_at: 'list' = <factory>) -> None

A drawing region plus the scales that map data into it.

  • point(x, y) -> 'Vec2' -- One data point in panel coordinates, in millimetres.
  • map(points: 'Iterable[Sequence]') -> 'tuple[Vec2, ...]' -- point() over a sequence: data pairs in, millimetres out.
  • region(x0, y0, x1, y1) -> 'Rect' -- Map two data corners to a normalized rectangle in panel coordinates.
  • draw(*items: 'Diagram', clip: 'bool | None' = None) -> "'Panel'" -- Add content already expressed in panel coordinates.
  • place(items, *, clip: 'bool | None' = None) -> "'Panel'" -- draw.place() in data coordinates: ((x, y), diagram) pairs, or bare diagrams that already know where they go.
  • marks(item: 'Diagram', points: 'Iterable[Sequence]', *, name: 'str | None' = None, **style) -> "'Panel'" -- A copy of item centred on every data point.
  • matrix(values: 'Sequence[Sequence[float]]', *, ramp=None, scale: 'Scale | None' = None, center: 'float | None' = None, x: 'Sequence | None' = None, y: 'Sequence | None' = None, overlap: 'float | None' = None, missing: 'str | None' = None, vector: 'str' = 'cells', interpolation: 'str' = 'nearest', samples: 'int' = 4, raster: 'bool | str' = 'auto', **style) -> "'Panel'" -- A 2D array of values, one coloured cell each.
  • line(points: 'Iterable[Sequence]', *, smooth: 'float' = 0.0, closed: 'bool' = False, name: 'str | None' = None, err=None, err_style: 'str' = 'band', simplify: 'float | str | None' = None, **style) -> "'Panel'" -- A path through data points: straight by default, curved with smooth.
  • band(x: 'Sequence', lo, hi, *, name: 'str | None' = None, color: 'str | None' = None, **style) -> "'Panel'" -- The shaded envelope between two edges over shared x.
  • scatter(points: 'Iterable[Sequence]', *, size=None, color=None, ramp=None, scale: 'Scale | None' = None, marker: 'str' = 'circle', name: 'str | None' = None, hollow: 'bool' = False, raster: 'bool' = False, dpi: 'float' = 300, **style) -> "'Panel'" -- Markers at data points, with size and colour that may be data too.
  • bars(at: 'Sequence', heights, *, width: 'float' = 0.8, baseline: 'float' = 0.0, orient: 'str' = 'v', stacked: 'bool | None' = None, grouped: 'bool | None' = None, gap: 'float' = 0.12, color=None, bar_colors=None, name: 'str | Sequence[str] | None' = None, labels=None, label_position: 'str' = 'auto', label_options: 'dict | None' = None, normalize: 'bool' = False, colors=<deprecated: use color=>, names=<deprecated: use name=>, **style) -> "'Panel'" -- A rectangle per value, standing on a baseline.
  • hist(values: 'Sequence[float]', bins: 'int | Sequence[float]' = 10, *, range: 'tuple[float, float] | None' = None, density: 'bool' = False, baseline: 'float' = 0.0, orient: 'str' = 'v', color=None, name: 'str | None' = None, histtype: 'str | None' = None, cumulative: 'bool' = False, prebinned: 'bool' = False, colors=<deprecated: use color=>, **style) -> "'Panel'" -- Binned counts as touching rectangles.
  • errorbars(points: 'Iterable[Sequence]', *, yerr=None, xerr=None, cap: 'float | None' = None, floor: 'str' = 'arrow', **style) -> "'Panel'" -- Whiskers through each point, in the data's own units.
  • fill(points: 'Iterable[Sequence]', *, baseline: 'float' = 0.0, orient: 'str' = 'v', name: 'str | None' = None, **style) -> "'Panel'" -- The area between a series and a baseline.
  • fill_between(x: 'Sequence', y0, y1, *, name: 'str | None' = None, **style) -> "'Panel'" -- The band between two curves over shared x -- a confidence envelope.
  • stackarea(x: 'Sequence', values, *, baseline=0.0, color=None, name: 'str | Sequence[str] | None' = None, colors=<deprecated: use color=>, names=<deprecated: use name=>, **style) -> "'Panel'" -- Stack non-negative series over shared x values, in supplied order.
  • step(points: 'Iterable[Sequence]', *, where: 'str' = 'post', name: 'str | None' = None, **style) -> "'Panel'" -- A staircase through the points, for a quantity that changes at instants rather than continuously.
  • boxplot(groups, *, at=None, width: 'float' = 0.6, orient: 'str' = 'v', whisker: 'float' = 1.5, outliers: 'bool' = True, color=None, colors=<deprecated: use color=>, **style) -> "'Panel'" -- Quartile boxes with Tukey whiskers, one per group.
  • violin(groups, *, at=None, width: 'float' = 0.8, orient: 'str' = 'v', bandwidth: 'float | None' = None, samples: 'int' = 64, cut: 'float' = 2.0, median: 'bool' = True, color=None, colors=<deprecated: use color=>, **style) -> "'Panel'" -- Mirrored kernel densities, one per group.
  • hline(y, *, span: 'tuple | None' = None, front: 'bool | None' = None, label: 'str | Diagram | None' = None, label_side: 'str | None' = None, label_offset: 'float | None' = None, name: 'str | None' = None, **style) -> "'Panel'" -- A horizontal rule at one data value of y.
  • vline(x, *, span: 'tuple | None' = None, front: 'bool | None' = None, label: 'str | Diagram | None' = None, label_side: 'str | None' = None, label_offset: 'float | None' = None, name: 'str | None' = None, **style) -> "'Panel'" -- A vertical rule at one data value of x -- stimulus onset, a dose, a cut point. span=(y0, y1) clips it in data coordinates.
  • vspan(x0, x1, *, front: 'bool' = False, name: 'str | None' = None, **style) -> "'Panel'" -- A shaded stripe between two data values of x, full height.
  • hspan(y0, y1, *, front: 'bool' = False, name: 'str | None' = None, **style) -> "'Panel'" -- A shaded stripe between two data values of y, full width.
  • rect(x0, y0, x1, y1, *, front: 'bool' = False, **style) -> "'Panel'" -- A rectangle whose four sides are data values -- a gated region, the extent of an inset, a box round a cluster.
  • under(*items: 'Diagram', clip: 'bool | None' = None) -> "'Panel'" -- Content that paints beneath everything else -- a backdrop, anything the data should sit on top of.
  • over(*items: 'Diagram', clip: 'bool | None' = None) -> "'Panel'" -- Content that paints above everything else, like an annotation.
  • background(**style) -> "'Panel'" -- Fill the plot area, beneath everything already in it.
  • outline(**style) -> "'Panel'" -- A rectangle around the area, drawn over the data.
  • grid(*, x: 'bool' = True, y: 'bool' = True, count: 'int' = 5, x_options: 'dict | None' = None, y_options: 'dict | None' = None, **style) -> "'Panel'" -- Rules at the tick positions, under the data.
  • axis(side: 'str' = 'bottom', *, at=None, **kwargs) -> "'Panel'" -- Hang an axis off one edge, built from this panel's own scale.
  • axes(x: 'str | None' = None, y: 'str | None' = None, *, x_options: 'dict | None' = None, y_options: 'dict | None' = None, **kwargs) -> "'Panel'" -- Bottom and left axes with shared and per-axis options.
  • twin_y(scale=None, *, side: 'str' = 'right', label: 'str | Diagram | None' = None, color: 'str | None' = None, axis: 'bool' = True, **kwargs) -> "'Panel'" -- A second y scale over the same area, and a handle that draws in it.
  • twin_x(scale=None, *, side: 'str' = 'top', label: 'str | Diagram | None' = None, color: 'str | None' = None, axis: 'bool' = True, **kwargs) -> "'Panel'" -- A second x scale over the same area -- wavelength above frequency, or a second time base. twin_y explains the shape of it.
  • title(content: 'str | Diagram', *, align: 'str' = 'center', pad: 'float | str | None' = None) -> "'Panel'" -- A heading over the panel, clear of whatever is already in it.
  • legend(*, corner: 'str | None' = 'ne', side: 'str | None' = None, entries: 'Sequence[tuple[str, object]] | None' = None, columns: 'int | str | None' = None, max_width: 'float | str | None' = None, swatch: 'float | str | None' = None, pad: 'float | str | None' = None, plate: 'bool | None' = None, title: 'str | None' = None, markup: 'bool' = True, order: 'str' = 'row', col_gap: 'float | str | None' = None, row_gap: 'float | str | None' = None, names: 'Sequence[str] | None' = None, **style) -> "'Panel'" -- A key built from the series this panel actually drew.
  • key_diagram(*, names: 'Sequence[str] | None' = None, columns: 'int | str' = 1, max_width: 'float | str | None' = None, font_size: 'float | str | None' = None, swatch: 'float | str | None' = None, order: 'str' = 'row', title: 'str | None' = None, markup: 'bool' = True, **style) -> 'Diagram' -- The key of this panel's named series as a diagram of its own.
  • colorbar(*, side: 'str' = 'right', source=None, corner: 'str | None' = None, scale: 'Scale | None' = None, length: 'float | str | None' = None, pad: 'float | str | None' = None, plate: 'bool' = False, title: 'str | None' = None, **kwargs) -> "'Panel'" -- The ramp this panel's matrix was coloured through, as a key beside it.
  • text(x, y, content: 'str | Diagram', *, anchor: 'str' = 'center', offset: 'Sequence[float]' = (0.0, 0.0), size: 'float | str | None' = None, markup: 'bool' = True, front: 'bool' = True, decorative: 'bool' = False, **style) -> "'Panel'" -- Words at one data point.
  • arrow(a: 'Sequence', b: 'Sequence', *, head: 'str' = 'triangle', label: 'str | Diagram | None' = None, front: 'bool' = True, **style) -> "'Panel'" -- An arrow from one data point to another.
  • annotate(x, y, text: 'str | Diagram', *, side: 'str' = 'n', clear: 'float | str | None' = None, leader: 'bool' = True, inside: 'bool' = True, dot: 'bool' = False, front: 'bool' = True, **kwargs) -> "'Panel'" -- A callout on one data point: a label clear of it, with a leader.
  • placed(x, y) -> 'Diagram' -- Build with the data rectangle's top-left at page (x, y) in mm.
  • guide(a, b, *, label=None, at=0.5, offset=1.0, label_style=None, **style) -> "'Panel'" -- A straight data guide with a label following its displayed direction.
  • build() -> 'Diagram' -- The panel as a diagram, centred like everything else, with its origin anchor on the centre of the plot area.
  • inset(sub, **kwargs) -> "'Panel'" -- Put a smaller panel in a corner of this one. See plot.inset.
  • bracket(x0, x1, y=None, **kwargs) -> "'Panel'" -- A grouping or significance bracket across a data span.
  • ribbon(a, b, **kwargs) -> "'Panel'" -- A Sankey band from data point a to data point b.
  • break_marks() -> "'Panel'" -- Draw the break glyph wherever a inklet.broken scale interrupts.
  • swarm(groups, *, at=None, width: 'float' = 0.8, max_width: 'float | str | None' = None, orient: 'str' = 'v', size: 'float | str | None' = None, gap: 'float | str | None' = None, marker: 'str' = 'circle', hollow: 'bool' = False, color=None, colors=<deprecated: use color=>, **style) -> "'Panel'" -- Every observation as its own dot, nudged sideways until none hides another.
  • dumbbell(at: 'Sequence', values, *, orient: 'str' = 'v', size: 'float | str | None' = None, color=None, name: 'str | Sequence[str] | None' = None, marker: 'str' = 'circle', connector: 'dict | None' = None, colors=<deprecated: use color=>, names=<deprecated: use name=>, **style) -> "'Panel'" -- Two or more dots per category joined by a line: a dumbbell plot.
  • lollipop(at: 'Sequence', values: 'Sequence', *, baseline: 'float' = 0.0, orient: 'str' = 'v', size: 'float | str | None' = None, color: 'str | None' = None, marker: 'str' = 'circle', stem: 'dict | None' = None, name: 'str | None' = None, **style) -> "'Panel'" -- One value per category as a dot on a stem from baseline.
  • ecdf(values: 'Sequence[float]', *, weights: 'Sequence[float] | None' = None, complementary: 'bool' = False, normalize: 'bool' = True, extend: 'bool' = True, name: 'str | None' = None, **style) -> "'Panel'" -- The empirical cumulative distribution of values as a step line.
  • ridgeline(groups, *, at=None, overlap: 'float' = 1.5, bandwidth: 'float | None' = None, samples: 'int' = 96, scale: 'str' = 'shared', fit: 'bool' = True, color=None, colors=<deprecated: use color=>, **style) -> "'Panel'" -- Overlapping kernel densities, one per category: a ridgeline plot.
  • raincloud(groups, *, at=None, orient: 'str' = 'h', width: 'float' = 0.9, bandwidth: 'float | None' = None, samples: 'int' = 64, cut: 'float' = 2.0, whisker: 'float' = 1.5, points: 'str | None' = 'jitter', size: 'float | str | None' = None, seed: 'int' = 0, box: 'bool' = True, color=None, colors=<deprecated: use color=>, **style) -> "'Panel'" -- A half violin, a narrow box and the observations, per group.
  • label_points(points: 'Iterable[Sequence]', labels: 'Sequence[str]', **kwargs) -> "'Panel'" -- Label many data points at once, clear of the marks and each other.
  • label_lines(name: 'str | Sequence[str] | None' = None, **kwargs) -> "'Panel'" -- Name curves at the curves themselves instead of in a legend.
  • dendrogram(tree, *, labels: 'Sequence | None' = None, orient: 'str' = 'v', threshold: 'float | None' = None, color=None, colors=<deprecated: use color=>, **style) -> "'Panel'" -- The merge tree of a hierarchical clustering, drawn as elbows.
  • clusters(groups: 'Sequence', *, color: 'str | None' = None, highlight=None, highlight_color: 'str | None' = None, width: 'float | str | None' = None, labels: 'bool' = False, size: 'float | str | None' = None, min_size: 'int' = 1, **style) -> "'Panel'" -- Boxes on the diagonal of a matrix, one per cluster.
  • correlogram(r, name: 'Sequence[str] | None' = None, *, triangle: 'str' = 'lower', shape: 'str' = 'circle', ramp=None, values=False, labels: 'bool' = True, size: 'float | str | None' = None, **style) -> "'Panel'" -- A correlation matrix as a triangle of glyphs sized and coloured by r.
  • ternary(points: 'Iterable[Sequence[float]]', *, labels: 'Sequence[str] | None' = None, ticks: 'int' = 5, grid: 'bool' = True, total: 'float' = 100, format=None, color=None, size=None, marker: 'str' = 'circle', name: 'str | None' = None, **style) -> "'Panel'" -- Compositions of three parts as points in a triangle.
  • treemap(data, *, color=None, highlight=None, highlight_color: 'str | None' = None, padding: 'float | str | None' = None, header: 'bool | None' = None, labels: 'bool' = True, values=None, sort: 'bool' = True, size: 'float | str | None' = None, **style) -> "'Panel'" -- A squarified treemap: each leaf a rectangle with area proportional to its value, filling the plot area.
  • icicle(data, *, orient: 'str' = 'h', root: 'bool | None' = None, gap: 'float | str | None' = None, spacing: 'float | str | None' = None, links: 'bool | None' = None, color=None, highlight=None, highlight_color: 'str | None' = None, labels='fit', levels: 'bool' = False, counts: 'bool' = False, sort: 'bool' = False, size: 'float | str | None' = None, **style) -> "'Panel'" -- An icicle (partition) chart: one band per level of a hierarchy, each node spanning its share of its parent.
  • sunburst(data, *, inner: 'float' = 0.3, start: 'float' = -90.0, color=None, highlight=None, highlight_color: 'str | None' = None, labels: 'bool' = True, center: 'str | None' = None, sort: 'bool' = False, size: 'float | str | None' = None, **style) -> "'Panel'" -- A sunburst: an icicle chart bent into rings about the centre of the plot area, the first level innermost.
  • network(nodes, edges, *, layout: 'str' = 'circular', order=None, size=None, top: 'float | None' = None, diameter: 'float | str | None' = None, floor: 'float | str | None' = None, shape: 'str' = 'circle', shapes=None, groups=None, color=None, labels='auto', label_size: 'float | str | None' = None, weights=None, width: 'float | str | None' = None, width_floor: 'float | str | None' = None, edge_color=None, bend: 'float | None' = None, arrows: 'bool' = False, opacity: 'float' = 0.85, gap: 'float | str | None' = None, iterations: 'int' = 300, **style) -> "'Panel'" -- A weighted network: node area from a value, edge width from a weight, colours from categories, fitted into the plot area.
  • width_key(source=None, *, side: 'str' = 'right', corner: 'str | None' = None, values: 'Sequence[float] | None' = None, count: 'int' = 3, format=None, title: 'str | None' = None, color: 'str | None' = None, length: 'float | str | None' = None, pad: 'float | str | None' = None, plate: 'bool' = False) -> "'Panel'" -- Reference lines with their weights: the key to an edge-width encoding.
  • chord(matrix, name: 'Sequence[str] | None' = None, *, color=None, gap: 'float' = 2.0, start: 'float' = -90.0, directed: 'bool' = False, sort: 'bool' = False, thickness: 'float | str | None' = None, pad: 'float | str | None' = None, labels: 'bool' = True, opacity: 'float' = 0.72, color_by: 'str' = 'source', size: 'float | str | None' = None, **style) -> "'Panel'" -- A chord diagram: groups as arcs around a ring, flows between them as ribbons through the middle, fitted into the plot area.
  • arc_diagram(nodes, edges, *, size=None, top: 'float | None' = None, diameter: 'float | str | None' = None, floor: 'float | str | None' = None, shape: 'str' = 'circle', shapes=None, groups=None, color=None, labels: 'bool' = True, rotate: 'float | None' = None, weights=None, width: 'float | str | None' = None, width_floor: 'float | str | None' = None, edge_color=None, directed: 'bool' = False, opacity: 'float' = 0.8, label_size: 'float | str | None' = None, **style) -> "'Panel'" -- An arc diagram: nodes in a row, each edge a half-ellipse arc above them whose width is the edge weight.
  • volcano(fold: 'Sequence[float]', p: 'Sequence[float]', *, labels: 'Sequence[str] | None' = None, top: 'int | None' = None, fold_threshold: 'float' = 1.0, p_threshold: 'float' = 0.05, color=None, name=None, size: 'float | None' = None, thresholds: 'bool' = True, label_options: 'dict | None' = None, highlight: 'Sequence[str] | None' = None, q: 'Sequence[float] | None' = None, colors=<deprecated: use color=>, names=<deprecated: use name=>, **style) -> "'Panel'" -- A volcano plot: log2 fold change on x against -log10 p on y.
  • ma(mean: 'Sequence[float]', fold: 'Sequence[float]', p: 'Sequence[float] | None' = None, *, labels: 'Sequence[str] | None' = None, top: 'int' = 10, fold_threshold: 'float' = 1.0, p_threshold: 'float' = 0.05, color=None, name=None, size: 'float | None' = None, log: 'bool' = True, zero: 'bool' = True, **style) -> "'Panel'" -- An MA plot: mean expression on x against log2 fold change on y.
  • dotplot(sizes: 'Sequence[Sequence[float]] | None' = None, colors=None, *, x: 'Sequence | None' = None, y: 'Sequence | None' = None, top: 'float | None' = None, diameter: 'float | str | None' = None, ramp=None, scale: 'Scale | None' = None, center: 'float | None' = None, color=None, size: 'Sequence[Sequence[float]] | None' = None, **style) -> "'Panel'" -- A dot plot: a circle per cell, its area one value, its colour another.
  • size_key(source=None, *, side: 'str' = 'right', corner: 'str | None' = None, values: 'Sequence[float] | None' = None, count: 'int' = 3, format=None, title: 'str | None' = None, orient: 'str | None' = None, pad: 'float | str | None' = None, plate: 'bool' = False, **style) -> "'Panel'" -- Reference circles with their values: the key to a size encoding.
  • kaplan_meier(data, *, confidence: 'float' = 0.95, band: 'str | None' = 'log-log', shade: 'bool' = True, censors: 'bool' = True, color=None, pvalue: 'float | str | None' = None, pvalue_corner: 'str' = 'sw', colors=<deprecated: use color=>, **style) -> "'Panel'" -- Kaplan-Meier survival curves, with censor ticks and confidence bands.
  • at_risk(*, ticks: 'Sequence | None' = None, count: 'int' = 5, title: 'str | None' = 'Number at risk', font_size: 'float | str | None' = None, pad: 'float | str | None' = None, **kwargs) -> "'Panel'" -- The number-at-risk table under the x axis of a kaplan_meier plot.
  • split_violin(first, second, *, at=None, orient: 'str' = 'v', width: 'float' = 0.8, bandwidth: 'float | None' = None, samples: 'int' = 64, cut: 'float' = 2.0, scale: 'str' = 'shared', median: 'bool' = True, quartiles: 'bool' = False, color=None, name: 'Sequence[str] | None' = None, colors=<deprecated: use color=>, names=<deprecated: use name=>, **style) -> "'Panel'" -- Two conditions per category as the two halves of one violin.
  • embedding(points: 'Iterable[Sequence]', clusters: 'Sequence', *, color=None, size=None, labels: 'bool' = True, center: 'str' = 'median', label_size: 'float | str | None' = None, arrows=None, shuffle: 'bool' = True, seed: 'int' = 0, raster: 'bool' = False, outline=None, outline_core: 'float' = 0.8, colors=<deprecated: use color=>, centre=<deprecated: use center=>, **style) -> "'Panel'" -- A UMAP or t-SNE style scatter, coloured and named by cluster.
  • brackets(comparisons: 'Sequence', *, format='stars', hide_ns: 'bool' = False, stars=None, ns: 'str' = 'ns', **kwargs) -> "'Panel'" -- Significance brackets for many pairs of groups, stacked clear of each other.
  • kde(values, *, bandwidth='scott', adjust: 'float' = 1.0, cut: 'float' = 3.0, samples: 'int' = 200, fill: 'bool' = False, stat: 'str' = 'density', orient: 'str' = 'v', color=None, name: 'str | None' = None, baseline: 'float' = 0.0, **style) -> "'Panel'" -- A kernel density curve, or one per group.
  • kde2d(points: 'Iterable[Sequence]', *, levels=5, fill: 'bool' = False, bandwidth='scott', adjust: 'float' = 1.0, gridsize: 'int' = 96, color=None, ramp=None, name: 'str | None' = None, **style) -> "'Panel'" -- Contours of a 2D kernel density: lines, or filled levels.
  • contour(x: 'Sequence[float]', y: 'Sequence[float]', z, *, levels=None, hdr=None, color=None, ramp=None, name: 'str | None' = None, **style) -> "'Panel'" -- Lines where a field gridded on x and y reaches each level.
  • hexbin(points: 'Iterable[Sequence]', *, gridsize: 'int' = 24, min_count: 'int' = 1, ramp=None, scale: 'Scale | None' = None, log: 'bool' = False, **style) -> "'Panel'" -- Points counted in hexagons, each coloured by its count.
  • hist2d(points: 'Iterable[Sequence]', bins=20, *, range=None, density: 'bool' = False, min_count: 'float' = 1, ramp=None, scale: 'Scale | None' = None, log: 'bool' = False, **style) -> "'Panel'" -- A 2D histogram: points counted in rectangular bins on continuous axes, each bin coloured by its count.
  • density_scatter(points: 'Iterable[Sequence]', *, bandwidth: 'float | None' = None, ramp=None, size=None, sort: 'bool' = True, raster: 'bool' = False, dpi: 'float' = 300, marker: 'str' = 'circle', **style) -> "'Panel'" -- A scatter coloured by how crowded each point's neighbourhood is.
  • regression(points: 'Iterable[Sequence]', *, method: 'str' = 'linear', confidence: 'float | None' = 0.95, prediction: 'bool' = False, scatter: 'bool' = True, frac: 'float' = 0.6666666666666666, iterations: 'int' = 3, span: 'tuple | None' = None, equation: 'bool | str' = False, color: 'str | None' = None, size=None, name: 'str | None' = None, **style) -> "'Panel'" -- Points with a fitted line and its confidence band.
  • residuals(points: 'Iterable[Sequence]', *, method: 'str' = 'linear', frac: 'float' = 0.6666666666666666, iterations: 'int' = 3, smooth: 'bool' = False, color: 'str | None' = None, size=None, name: 'str | None' = None, **style) -> "'Panel'" -- The residuals of a fit against x, with a zero line.
  • qq(values: 'Sequence[float]', *, dist='normal', line: 'str | None' = 'quartiles', color: 'str | None' = None, size=None, name: 'str | None' = None, **style) -> "'Panel'" -- A normal quantile-quantile plot: sample against theoretical quantiles, with a reference line.
  • pp(values: 'Sequence[float]', *, dist='normal', color: 'str | None' = None, size=None, name: 'str | None' = None, **style) -> "'Panel'" -- A probability-probability plot against a fitted normal.
  • bland_altman(a: 'Sequence[float]', b: 'Sequence[float]', *, z: 'float' = 1.96, percent: 'bool' = False, confidence: 'float | None' = None, labels: 'bool' = True, format: 'str' = '{:.2f}', color: 'str | None' = None, size=None, name: 'str | None' = None, **style) -> "'Panel'" -- A Bland-Altman (mean-difference) plot of two methods' agreement.
  • boxen(groups, *, at=None, width: 'float' = 0.8, orient: 'str' = 'v', depth='tukey', outliers: 'bool' = True, color=None, size=None, **style) -> "'Panel'" -- Letter-value (boxen) plots: nested boxes out into the tails.
  • strip(groups, *, at=None, width: 'float' = 0.8, jitter: 'float' = 0.5, orient: 'str' = 'v', size=None, seed: 'int' = 0, color=None, marker: 'str' = 'circle', **style) -> "'Panel'" -- A strip plot: each group's observations, jittered across its slot.
  • sina(groups, *, at=None, width: 'float' = 0.8, orient: 'str' = 'v', bandwidth='scott', adjust: 'float' = 1.0, size=None, seed: 'int' = 0, color=None, marker: 'str' = 'circle', **style) -> "'Panel'" -- A sina plot: points jittered within their group's density.
  • waterfall(at: 'Sequence', values: 'Sequence', *, totals=(), baseline: 'float' = 0.0, orient: 'str' = 'v', width: 'float' = 0.6, color=None, connectors: 'bool' = True, labels=None, name: 'Sequence[str] | None' = None, **style) -> "'Panel'" -- A waterfall chart: signed changes as bars floating on a running total.
  • slope(values: 'Mapping[str, Sequence[float]]', *, at: 'Sequence | None' = None, labels: 'str' = 'both', format=None, color=None, highlight=None, size: 'float | str | None' = None, name: 'bool' = True, **style) -> "'Panel'" -- A slope chart: each series' values at a few time points, joined.
  • bump(values: 'Mapping[str, Sequence[float]]', *, at: 'Sequence | None' = None, ranked: 'bool' = False, labels: 'str' = 'both', color=None, highlight=None, size: 'float | str | None' = None, numbers: 'bool' = False, **style) -> "'Panel'" -- A bump chart: the rank of each series at each time point.
  • stem(points: 'Iterable[Sequence]', *, baseline: 'float' = 0.0, orient: 'str' = 'v', color: 'str | None' = None, marker: 'str' = 'circle', size: 'float | str | None' = None, hollow: 'bool' = False, rule: 'bool' = True, name: 'str | None' = None, **style) -> "'Panel'" -- A stem plot: a stem from baseline to a dot at each (x, y).
  • likert(at: 'Sequence', counts: 'Sequence[Sequence[float]]', *, neutral: 'int | None' = None, normalize: 'bool' = True, orient: 'str' = 'h', width: 'float' = 0.7, color=None, name: 'str | Sequence[str] | None' = None, labels=None, zero: 'bool' = True, **style) -> "'Panel'" -- Diverging stacked bars for Likert-scale responses, centred on neutral.
  • diverging_bars(at: 'Sequence', left, right, *, orient: 'str' = 'h', width: 'float' = 0.7, color=None, name: 'str | Sequence[str] | None' = None, reference=None, titles: 'Sequence[str] | None' = None, zero: 'bool' = True, **style) -> "'Panel'" -- Two quantities per category, back to back: left of zero and right.
  • pyramid(at: 'Sequence', left, right, *, titles: 'Sequence[str] | None' = None, color=None, width: 'float' = 0.92, **kwargs) -> "'Panel'" -- A population pyramid: diverging_bars with touching bars.
  • waffle(values: 'Sequence[float]', *, rows: 'int' = 10, columns: 'int' = 10, total: 'float | None' = None, color=None, name: 'str | Sequence[str] | None' = None, gap: 'float' = 0.18, order: 'str' = 'column', **style) -> "'Panel'" -- A waffle chart: shares of a whole as cells of a grid.
  • mosaic(at: 'Sequence', values, *, color=None, name: 'str | Sequence[str] | None' = None, gap: 'float | str' = 0.6, labels=None, categories: 'bool' = True, **style) -> "'Panel'" -- A mosaic (Marimekko) chart: stacked bars as wide as their totals.
  • streamgraph(x: 'Sequence', values, *, offset: 'str' = 'wiggle', order: 'str' = 'input', color=None, name: 'str | Sequence[str] | None' = None, smooth: 'float' = 0.5, **style) -> "'Panel'" -- A streamgraph: stacked areas around a moving baseline.
  • parallel(rows, *, dimensions: 'Sequence | None' = None, ranges=None, color=None, groups: 'Sequence | None' = None, count: 'int' = 4, format=None, labels: 'bool' = True, **style) -> "'Panel'" -- Parallel coordinates: an axis per variable and a line per record.
  • bullet(at: 'Sequence', values: 'Sequence[float]', *, targets=None, ranges=None, baseline: 'float' = 0.0, orient: 'str' = 'h', width: 'float' = 0.7, color: 'str | None' = None, **style) -> "'Panel'" -- Bullet charts: a measure bar against a target and qualitative ranges.
  • gantt(tasks: 'Sequence[Sequence]', *, groups: 'Sequence | None' = None, color=None, width: 'float' = 0.6, labels: 'bool' = False, **style) -> "'Panel'" -- A Gantt chart: a bar per task from its start to its end.
  • timeline(events: 'Sequence[Sequence]', *, at: 'float | None' = None, color: 'str | None' = None, size: 'float | str | None' = None, levels: 'Sequence[int] | None' = None, line: 'bool' = True, **style) -> "'Panel'" -- An event timeline: labelled stems off a base line.
  • calendar(values: 'Mapping', *, start=None, end=None, ramp=None, scale: 'Scale | None' = None, center: 'float | None' = None, week_start: 'str | int' = 'monday', gap: 'float | str' = 0.25, labels: 'bool' = True, **style) -> "'Panel'" -- A calendar heatmap: a square per day, a column per week.
  • barplot(at: 'Sequence', data, *, estimator: 'str' = 'mean', error='sem', points: 'bool' = True, width: 'float' = 0.8, gap: 'float' = 0.12, orient: 'str' = 'v', color=None, name: 'str | Sequence[str] | None' = None, size: 'float | str | None' = None, cap: 'float | str | None' = None, baseline: 'float' = 0.0, **style) -> "'Panel'" -- Bars of the mean with error bars and every observation as a dot.

row(panels: 'Iterable[Panel | Diagram]', gap: 'float | str | None' = None, align: 'str' = 'center') -> 'Diagram'

Panels side by side, their plot areas on one line.

column(panels: 'Iterable[Panel | Diagram]', gap: 'float | str | None' = None, align: 'str' = 'center') -> 'Diagram'

Panels stacked, their plot areas on one vertical line.

axis(scale: 'Scale', *, side: 'str' = 'bottom', label: 'str | Diagram | None' = None, ticks: 'Sequence | None' = None, count: 'int' = 5, format: 'Callable[[object], str] | str | None' = None, si: 'bool' = False, length: 'float | str | None' = None, tick_size: 'float | str | None' = None, tick_pad: 'float | str | None' = None, label_pad: 'float | str | None' = None, spine: 'bool' = True, thin: 'bool | None' = None, labels: 'bool' = True, rotate: 'float' = 0.0, tnum: 'bool' = True, markup: 'bool | None' = None, offset: 'bool | str | None' = None, minor: 'bool | int' = False, minor_size: 'float | str | None' = None, tick_font_size: 'float | str | None' = None, label_font_size: 'float | str | None' = None, kind: 'str' = 'axis', **style) -> 'Diagram'

One axis of a plot.

colorbar(source, *, domain: 'tuple[float, float]' = (0.0, 1.0), scale: 'Scale | None' = None, length: 'float | str | None' = None, thickness: 'float | str | None' = None, side: 'str' = 'right', label: 'str | None' = None, ticks: 'Sequence | None' = None, count: 'int' = 5, format: 'Callable[[object], str] | None' = None, steps: 'int' = 128, outline: 'bool' = True, thin: 'bool | None' = None, tick_font_size: 'float | str | None' = None, label_font_size: 'float | str | None' = None, kind: 'str' = 'colorbar', **style) -> 'Diagram'

A continuous ramp with an axis against it.

legend(entries: 'Sequence[tuple[str, object]]', *, columns: 'int | str' = 1, max_width: 'float | str | None' = None, font_size: 'float | str | None' = None, swatch: 'float | str | None' = None, gap: 'float | str | None' = None, row_gap: 'float | str | None' = None, col_gap: 'float | str | None' = None, order: 'str' = 'row', title: 'str | None' = None, markup: 'bool' = True, kind: 'str' = 'legend', **style) -> 'Diagram'

Swatches and their names.

linear(domain: 'tuple[float, float]' = (0.0, 1.0), range: 'Range' = (0.0, 1.0), *, clamp: 'bool' = False, nice: 'bool' = False) -> 'Linear'

A proportional scale. nice=True rounds the domain out to whole ticks.

log(domain: 'tuple[float, float]' = (1.0, 10.0), range: 'Range' = (0.0, 1.0), *, base: 'float' = 10.0, clamp: 'bool' = False) -> 'Log'

A logarithmic scale. The domain must not span or touch zero.

symlog(domain: 'tuple[float, float]' = (-1.0, 1.0), range: 'Range' = (0.0, 1.0), *, linthresh: 'float' = 1.0, base: 'float' = 10.0) -> 'SymLog'

Logarithmic away from zero, linear across it.

band(categories: 'Sequence', range: 'Range' = (0.0, 1.0), *, padding: 'float' = 0.1, outer: 'float | None' = None) -> 'Band'

A categorical scale: one evenly spaced slot per category.

grouped_band(groups: 'Sequence[Sequence] | Mapping', range: 'Range' = (0.0, 1.0), *, gap: 'float' = 1.0, padding: 'float' = 0.1, outer: 'float | None' = None, reverse: 'bool' = False) -> 'GroupedBand'

A band scale with gaps between groups, measured in category slots.

broken(domain: 'tuple[float, float]' = (0.0, 1.0), range: 'Range' = (0.0, 1.0), *, breaks: 'Sequence[Sequence[float]]' = (), gap: 'float | None' = None, weights: 'Sequence[float] | None' = None) -> 'Broken'

A linear scale with breaks cut out of it.

dates(domain=('1970-01-01', '1970-01-02'), range: 'Range' = (0.0, 1.0), *, clamp: 'bool' = False, nice: 'bool' = False) -> 'Time'

A time axis over (start, end).

class Scale()

Data to millimetres. Subclasses fill in map, invert and ticks.

  • map(value) -- One data value to its millimetre position along this scale.
  • invert(position: 'float') -- The reverse of map: millimetres back to a data value.
  • ticks(count: 'int' = 5) -> 'tuple' -- About count round values to label, chosen to suit the scale.
  • with_range(lo: 'float', hi: 'float') -> "'Scale'" -- The same scale measuring into a different span of millimetres.
  • tick_labels(ticks: 'Sequence') -> 'tuple[str, ...]' -- Labels for a set of ticks, formatted against their own spacing.
  • minor_ticks(majors: 'Sequence', count: 'int | None' = None, clear: 'float' = 0.0) -> 'tuple' -- Unlabelled subdivisions between the major ticks.
  • positions(values: 'Sequence') -> 'tuple[float, ...]' -- map over a sequence of values.

ramp(stops: 'str | Palette | Sequence[str]', *, space: 'str' = 'lab') -> 'Ramp'

A ramp from a palette, the name of one, or a list of colours.

class Ramp(stops: 'tuple[str, ...]', space: 'str' = 'lab') -> None

A colour ramp, sampled at t in 0..1. Call it, or ask it for n stops.

  • sample(count: 'int') -> 'tuple[str, ...]' -- count colours spanning the ramp, ends included.
  • reversed() -> "'Ramp'" -- The same colours end to end, for a scale that runs the other way.

class CategorySet(_entries: 'tuple', _groups: 'tuple' = ()) -> None

An immutable colour mapping. Use categories() to construct one.

  • subset(keys) -- Select categories in their original order; reject unknown/empty selections.
  • scale(range=(0.0, 1.0), *, reverse=False, gap=1.0, padding=0.1, outer=None) -- A categorical axis; reverse=True reads top to bottom on y.
  • group_labels(panel, *, side='bottom', pad=None, **style) -- Add group brackets outside a panel, after its axes have been added.
  • get(key, default=None) -- D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.
  • items() -- D.items() -> a set-like object providing a view on D's items
  • keys() -- D.keys() -> a set-like object providing a view on D's keys
  • values() -- D.values() -> an object providing a view on D's values

categories(colors: 'Mapping', *, labels: 'Mapping | None' = None, groups: 'Mapping | None' = None) -> 'CategorySet'

Define category colours and order once for scales, bars, keys and groups.

inset(panel, sub, *, corner: 'str' = 'ne', width: 'float | None' = 0.35, pad: 'float | str | None' = None, side: 'str | None' = None, align: 'str' = 'center', zoom: 'Sequence[float] | None' = None, plate: 'bool' = True, connect: 'bool' = True, connector: 'dict | None' = None, **style)

Put sub inside panel's plot area, on a plate, and return panel.

ribbon(a: 'Point', b: 'Point', *, width0: 'float', width1: 'float | None' = None, along: 'Point | None' = None, ease: 'float' = 0.55, align: 'str' = 'center', kind: 'str' = 'mark', **style) -> 'Diagram'

A band from a to b, width0 wide at one end and width1 at the other.

facets(panels: 'Sequence[Panel | Diagram]', *, cols: 'int | None' = None, share_x: 'bool' = True, share_y: 'bool' = True, x_label: 'str | Diagram | None' = None, y_label: 'str | Diagram | None' = None, gap: 'float | str | None' = None, row_gap: 'float | str | None' = None, axes: 'bool' = True, label_pad: 'float | str | None' = None, **axis_kwargs) -> 'Diagram'

A grid of panels with one set of axes between them.

histogram(values: 'Sequence[float]', bins: 'int | Sequence[float]' = 10, *, range: 'tuple[float, float] | None' = None, density: 'bool' = False) -> 'tuple[tuple[float, ...], tuple[float, ...]]'

Bin edges and the height of each bin: (edges, heights).

upset(data, *, sets: 'Sequence[str] | None' = None, sort: 'str' = 'size', sort_sets: 'bool' = True, min_size: 'float' = 1, max_intersections: 'int | None' = None, empty: 'bool' = False, set_sizes: 'bool' = True, width: 'float | str | None' = None, height: 'float | str' = 26, matrix_height: 'float | str | None' = None, set_width: 'float | str' = 16, color: 'str | None' = None, labels=None, stripes: 'bool' = True, bar_label: 'str | None' = 'intersection size', set_label: 'str | None' = 'set size', gap: 'float | str | None' = None, count: 'int' = 4) -> 'Diagram'

An UpSet plot: intersection sizes as bars over a membership matrix.

forest(rows: 'Sequence', *, log: 'bool' = False, limits: 'tuple[float, float] | None' = None, null: 'float | None' = None, left: 'Sequence' = ('label',), right: 'Sequence' = ('ci',), headers: 'bool' = True, measure: 'str' = 'Estimate', digits: 'int' = 2, label: 'str | None' = None, ticks: 'Sequence[float] | None' = None, width: 'float | str' = 36, row_height: 'float | str | None' = None, color: 'str | None' = None, summary_color: 'str | None' = None, size: 'float | str | None' = None, summary_line: 'bool' = False, gap: 'float | str | None' = None, count: 'int' = 5, text_size: 'float | str | None' = None) -> 'Diagram'

A forest plot: one estimate and confidence interval per row, with aligned text columns beside it.

pairplot(data: 'Mapping[str, Sequence[float]]', *, vars: 'Sequence[str] | None' = None, groups: 'Sequence | None' = None, cell: 'float | str' = 26, diag: 'str | None' = 'auto', lower: 'str | None' = 'scatter', upper: 'str | None' = 'scatter', corner: 'bool' = False, bins: 'int' = 12, log: 'Sequence[str]' = (), labels: 'Mapping[str, str] | None' = None, color=None, size=None, legend: 'bool' = True, gap: 'float | str | None' = None, count: 'int' = 4, **style) -> 'Diagram'

Every pair of variables against each other, in one aligned grid.

jointplot(points: 'Sequence[Sequence[float]]', *, kind: 'str' = 'scatter', marginal: 'str' = 'hist', groups: 'Sequence | None' = None, width: 'float | str' = 50, ratio: 'float' = 4.0, x=None, y=None, x_log: 'bool' = False, y_log: 'bool' = False, bins: 'int' = 20, x_label: 'str | None' = None, y_label: 'str | None' = None, color=None, size=None, legend: 'bool' = True, gap: 'float | str | None' = None, count: 'int' = 5, **style) -> 'Diagram'

One pair of variables with both marginal distributions.

clustermap(values, *, rows: 'Sequence[str] | None' = None, columns: 'Sequence[str] | None' = None, method: 'str' = 'average', metric='euclidean', row_cluster: 'bool' = True, col_cluster: 'bool' = True, row_linkage=None, col_linkage=None, standardize: 'str | None' = None, k: 'int | None' = None, highlight=None, row_color: 'Mapping | None' = None, col_color: 'Mapping | None' = None, ramp=None, scale=None, center: 'float | None' = None, width: 'float | str' = 50, height: 'float | str | None' = None, tree: 'float | str' = 8, strip: 'float | str' = 2.0, label: 'str | None' = None, row_labels: 'bool | None' = None, col_labels: 'bool | None' = None, colorbar: 'bool' = True, gap: 'float | str | None' = None) -> 'Diagram'

A matrix reordered by hierarchical clustering, with row and column dendrograms, annotation strips and a colorbar.

manhattan(chromosome: 'Sequence', position: 'Sequence[float]', p: 'Sequence[float]', *, labels: 'Sequence[str] | None' = None, top: 'int' = 5, threshold: 'float | None' = 5e-08, suggestive: 'float | None' = 1e-05, window: 'float' = 1000000.0, order: 'Sequence[str] | None' = None, color: 'str | Sequence[str] | None' = None, highlight=None, highlight_color: 'str | None' = None, bands: 'bool' = False, width: 'float | str' = 120, height: 'float | str' = 40, ymax: 'float | None' = None, size: 'float | None' = None, gap: 'float' = 0.008, raster: 'bool' = False, **style)

A Manhattan plot as a panel with its axes, ready for more layers.

polar(radius: 'float | str' = 30.0, *, r=None, theta=None, zero: 'float | str | None' = None, winding: 'str | None' = None, unit: 'str' = 'deg', hole: 'float | str' = 0.0, clip: 'bool' = False, nice: 'bool' = False) -> 'PolarPanel'

A polar plot area of a given rim radius.

class PolarPanel(radius: 'float', r: 'Scale', theta: 'Theta', hole: 'float' = 0.0, clip: 'bool' = False, _under: 'list[Diagram]' = <factory>, _content: 'list[Diagram]' = <factory>, _over: 'list[Diagram]' = <factory>, _title: 'tuple[Diagram, float] | None' = None, _built: 'Diagram | None' = None, _keys: 'list[SeriesKey]' = <factory>, _spokes: 'list[float]' = <factory>, _ring: 'list[tuple[float, Rect]]' = <factory>, _pie: 'tuple | None' = None, _free: 'tuple[bool, bool]' = (False, False), _journal: 'list' = <factory>, _depth: 'int' = 0, _replayable: 'bool' = True, _ring_values: 'tuple | None' = None, _radar_data: 'list' = <factory>, _breakout_clear: 'tuple | None' = None, _theta_axes: 'list' = <factory>) -> None

A disc, or a fan of one, plus the scales that map data into it.

  • angle(theta: 'float') -> 'float' -- One data angle in page degrees -- east is 0, clockwise is positive.
  • reach(r: 'float') -> 'float' -- One data radius in millimetres from the pole.
  • point(theta, r) -> 'Vec2' -- One data point in panel coordinates, in millimetres.
  • map(points: 'Iterable[Sequence]') -> 'tuple[Vec2, ...]' -- point() over a sequence: (theta, r) pairs in, millimetres out.
  • draw(*items: 'Diagram', clip: 'bool | None' = None) -> "'PolarPanel'" -- Add content already expressed in panel coordinates.
  • under(*items: 'Diagram', clip: 'bool | None' = None) -> "'PolarPanel'" -- Add content beneath the data.
  • over(*items: 'Diagram', clip: 'bool | None' = None) -> "'PolarPanel'" -- Add content above the data.
  • place(items, *, clip: 'bool | None' = None) -> "'PolarPanel'" -- draw.place() in data coordinates: ((theta, r), diagram) pairs.
  • background(**style) -> "'PolarPanel'" -- Fill the data region, beneath everything already in it.
  • spine(*, rim: 'bool' = True, edges: 'bool | None' = None, **style) -> "'PolarPanel'" -- The rim, and for a fan the two straight edges, drawn over the data.
  • outline(*, rim: 'bool' = True, edges: 'bool | None' = None, **style) -> "'PolarPanel'" -- The rim, and for a fan the two straight edges, drawn over the data.
  • grid(*, r: 'bool' = True, theta: 'bool' = True, r_count: 'int' = 4, theta_count: 'int' = 8, r_ticks: 'Sequence | None' = None, theta_ticks: 'Sequence | None' = None, **style) -> "'PolarPanel'" -- Rings at the r ticks and spokes at the theta ticks, under the data.
  • theta_axis(*, count: 'int' = 8, ticks: 'Sequence | None' = None, labels: 'bool' = True, format=None, label: 'str | Diagram | None' = None, spine: 'bool' = True, tick_size: 'float | str | None' = None, pad: 'float | str | None' = None, label_pad: 'float | str | None' = None, thin: 'bool' = True, curved: 'bool' = False, kind: 'str' = 'axis', **style) -> "'PolarPanel'" -- Ticks round the rim, their angles written outside it.
  • r_axis(*, at: 'float | None' = None, count: 'int' = 4, ticks: 'Sequence | None' = None, labels: 'bool' = True, format=None, si: 'bool' = False, label: 'str | Diagram | None' = None, side: 'str | None' = None, spine: 'bool' = False, plate: 'bool | None' = None, tick_size: 'float | str | None' = None, pad: 'float | str | None' = None, label_pad: 'float | str | None' = None, kind: 'str' = 'axis', **style) -> "'PolarPanel'" -- The radial scale, written along one spoke.
  • title(content: 'str | Diagram', *, pad: 'float | str | None' = None) -> "'PolarPanel'" -- A heading over the panel, clear of whatever is already in it.
  • line(points: 'Iterable[Sequence]', *, closed: 'bool | None' = None, interpolate: 'bool' = True, name: 'str | None' = None, **style) -> "'PolarPanel'" -- A path through (theta, r) points -- a tuning curve, a radiation pattern, a profile round a cell.
  • scatter(points: 'Iterable[Sequence]', *, size=None, color=None, marker: 'str' = 'circle', name: 'str | None' = None, **style) -> "'PolarPanel'" -- Markers at (theta, r) points, with size and colour that may be data too. The rectangular Panel.scatter in polar coordinates: the same call, through this panel's own point().
  • marks(item: 'Diagram', points: 'Iterable[Sequence]', *, name: 'str | None' = None, **style) -> "'PolarPanel'" -- A copy of item centred on every (theta, r) point.
  • band(theta: 'Sequence', low, high, *, closed: 'bool | None' = None, interpolate: 'bool' = True, name: 'str | None' = None, color: 'str | None' = None, **style) -> "'PolarPanel'" -- The region between two radii at each angle: a spread round a curve.
  • rose(heights: 'Sequence[float]', *, at: 'Sequence[float] | None' = None, width: 'float' = 1.0, base: 'float | None' = None, name: 'str | None' = None, color: 'str | None' = None, **style) -> "'PolarPanel'" -- Sector bars: the wind rose, and every circular histogram there is.
  • radar(values: 'Sequence[float]', *, name: 'str | None' = None, color: 'str | None' = None, fill: 'bool' = True, markers: 'bool' = True, size: 'float | str | None' = None, **style) -> "'PolarPanel'" -- One series of a radar chart: a closed polygon with a value per spoke.
  • radar_grid(categories: 'Sequence[str]', *, rings=None, shape: 'str' = 'polygon', labels: 'bool' = True, values: 'bool' = False, **style) -> "'PolarPanel'" -- The rings, spokes and category names of a radar chart.
  • pie(values: 'Sequence[float]', *, name: 'Sequence[str] | None' = None, color=None, labels='percent', label_options: 'dict | None' = None, separator: 'bool' = True, names=<deprecated: use name=>, colors=<deprecated: use color=>, **style) -> "'PolarPanel'" -- A pie chart, or a donut on a panel made with hole=.
  • breakout(slices, parts: 'Sequence[float] | None' = None, *, color=None, name: 'Sequence[str] | None' = None, labels='percent', label_options: 'dict | None' = None, side: 'str' = 'right', width: 'float | str | None' = None, height: 'float | str | None' = None, gap: 'float | str | None' = None, title: 'str | None' = None, title_side: 'str' = 'top', connector: 'dict | None' = None, separator: 'bool' = True, colors=<deprecated: use color=>, names=<deprecated: use name=>, **style) -> "'PolarPanel'" -- Expand slices of the pie into a stacked bar beside it.
  • mean_vector(angles: 'Sequence[float]', weights: 'Sequence[float] | None' = None, *, r: 'float | None' = None, order: 'int' = 1, head: 'str' = 'triangle', label: 'str | Diagram | None' = None, name: 'str | None' = None, color: 'str | None' = None, **style) -> "'PolarPanel'" -- The circular mean of angles, drawn as an arrow from the pole.
  • text(theta, r, content: 'str | Diagram', *, anchor: 'str' = 'center', offset: 'Sequence[float]' = (0.0, 0.0), size: 'float | str | None' = None, markup: 'bool' = True, **style) -> "'PolarPanel'" -- Writing at one data point, anchor of it on that point.
  • legend(*, corner: 'str | None' = 'ne', side: 'str | None' = None, entries: 'Sequence[tuple[str, object]] | None' = None, columns: 'int' = 1, swatch: 'float | str | None' = None, pad: 'float | str | None' = None, plate: 'bool | None' = None, title: 'str | None' = None, markup: 'bool' = True, names: 'Sequence[str] | None' = None, **style) -> "'PolarPanel'" -- A key built from the series this panel actually drew.
  • build() -> 'Diagram' -- The panel as a diagram, with its origin anchor on the pole.

theta_ticks(low: 'float', high: 'float', count: 'int' = 8, *, unit: 'str' = 'deg', closed: 'bool' = False) -> 'tuple[float, ...]'

Return readable angular tick values between low and high.

circular_mean(angles: 'Sequence[float]', weights: 'Sequence[float] | None' = None, *, unit: 'str' = 'deg', order: 'int' = 1) -> 'tuple[float, float]'

The mean direction of a set of angles, and how concentrated they are.

circular_histogram(angles: 'Sequence[float]', bins: 'int' = 12, *, unit: 'str' = 'deg', domain: 'tuple[float, float] | None' = None, density: 'bool' = False) -> 'tuple[tuple[float, ...], tuple[float, ...]]'

Bin angles into equal sectors: (centres, heights) for rose().

class AnatomyView(view: 'View', width: 'float', height: 'float', _layers: 'list' = <factory>) -> None

A fixed viewport with named surfaces, paths and markers in one camera.

  • surface(name, mesh, **style)
  • paths(name, lines, **style)
  • markers(name, points, **style)
  • style(name, **changes) -- Restyle one named layer without refitting its geometry or siblings.
  • zoom(focus, *, width, height, pad=1, layers=None) -- Reframe selected layers in the same camera orientation and projection.
  • window(detail) -- The detail's full viewport, expressed in this overview's coordinates.
  • lighting(direction=(-0.4, -0.6, -1), *, levels=16, smooth=80) -- Set one smooth-lighting treatment across all current surfaces.
  • cut(normal, offset=0) -- Section all layers in source coordinates without changing the camera.
  • build(*, depth='layers') -- Render all layers into a clipped, fixed-size native vector viewport.
  • inset(focus, *, width, height, corner='ne', side=None, gap=2, layers=None, **style) -- Overview plus a registered inset or external detail, with locator lines.

anatomy_view(reference, *, width, height, camera='front', pad=1)

Fit one camera to a reference mesh and author layers without projections.

model(source: 'str | Path | Mesh', *, width: 'float | str | None' = None, height: 'float | str | None' = None, view: 'Camera | View | str | tuple[float, float] | None' = None, style: 'str' = 'lineart', shading: 'str | None' = None, sort: 'str' = 'auto', opacity: 'float' = 1.0, occlusion: 'float' = 0.0, backend: 'str' = 'builtin', crease: 'float' = 30.0, ridges: 'bool | Mapping[str, bool]' = True, hidden: 'bool' = True, cull: 'bool | None' = None, smooth: 'bool | float | None' = None, up_axis: 'str' = 'z', at: 'Sequence[float] | Vec3 | None' = None, spin: 'Any' = None, scale: 'float | Sequence[float] | None' = None, transform: 'Mat4 | None' = None, repair: 'bool' = False, ink: 'str | None' = None, color: 'str | None' = None, colors: 'Mapping[str, str] | None' = None, stroke_width: 'float | str | None' = None, stroke_widths: 'Mapping[str, float | str] | None' = None, creases: 'Mapping[str, float] | None' = None, light: 'Vec3 | None' = None, levels: 'int | None' = None, depth_cue: 'float | None' = None, lift: 'float | None' = None, shade: 'float | None' = None, anchors: 'Mapping[str, Sequence[float]] | None' = None, groups: 'bool' = True, options: 'Sequence[tuple[str, Any]]' = (), name: 'str | None' = None) -> 'Diagram'

Draw a mesh -- from a file or already in hand -- as vector line art.

solid(kind: 'str' = 'cube', *, tolerance: 'float | None' = 0.06, **options) -> 'Diagram'

A parametric solid, with no asset file involved.

scene(parts, *, width: 'float | str | None' = None, height: 'float | str | None' = None, view: 'Camera | str | tuple[float, float] | None' = None, order: 'str' = 'parts', assert_order: 'Sequence[tuple[str, str]]' = (), name: 'str' = 'scene', **shared) -> 'Diagram'

Several meshes in one projection, painted back to front.

axes(*, width: 'float | str' = 26.0, view: 'Camera | str | tuple[float, float] | None' = 'isometric', labels: 'Sequence[str] | None' = ('x', 'y', 'z'), style: 'str' = 'shaded', length: 'float' = 1.0, thickness: 'float' = 1.0, gap: 'float | None' = None, label_size: 'float | str | None' = None, name: 'str' = 'axes', tolerance: 'float | None' = 0.06, **options) -> 'Diagram'

Draw three coordinate arrows and their labels.

cartoon(chain: 'Chain', *, name: 'str' = 'cartoon', group: 'str | None' = None, sides: 'int' = 12, steps: 'int' = 6) -> 'Mesh'

The whole chain: one ribbon per continuous segment, merged.

class Mesh(vertices: 'tuple[Vec3, ...]', faces: 'tuple[tuple[int, int, int], ...]', groups: 'tuple[str, ...]' = (), name: 'str' = '', _derived: 'dict' = <factory>) -> None

Mesh(vertices: 'tuple[Vec3, ...]', faces: 'tuple[tuple[int, int, int], ...]', groups: 'tuple[str, ...]' = (), name: 'str' = '', _derived: 'dict' = )

  • from_arrays(vertices, faces, *, groups=(), name='') -- Build from iterable XYZ coordinates and triangle indices.
  • clipped(normal, offset=0) -- Keep the half-space normal·point >= offset, with an open cut boundary.
  • simplified(target_faces: 'int') -- Return a quadric-error display approximation with fewer triangles.
  • rough_vertices(degrees: 'float') -> 'frozenset[int]' -- Vertices with a fold, a border or a branch somewhere around them.
  • group_center(name: 'str') -> 'Vec3' -- Centroid of the vertices belonging to a named group, area-weighted by nothing: a plain average of the distinct vertices the group touches. Area weighting would drag the point toward whichever end of a part happened to be finely tessellated.
  • transformed(matrix: 'Mat4') -> 'Mesh' -- Move the mesh. A mirroring transform reverses every winding, because the alternative is a solid whose normals all point inward and whose silhouette comes out inside-out.
  • merged(*others: 'Mesh') -> 'Mesh' -- Concatenate, keeping each part's group names.
  • grouped(name: 'str') -> 'Mesh' -- The same geometry with every face labelled, for merged to keep.
  • centered() -> 'Mesh'
  • scaled_to_fit(size: 'float') -> 'Mesh' -- Uniformly scale so the longest bounding-box side is size.
  • drill(axis: 'str | Sequence[float] | Vec3' = 'z', *, radius: 'float', at: 'Sequence[float] | Vec3 | None' = None, segments: 'int' = 20, group: 'str | None' = None) -> 'Mesh' -- A cylindrical hole straight through the solid, both sides open.
  • subtract(tool: 'Mesh') -> 'Mesh' -- This mesh with tool removed. Needs trimesh; drill does not.
  • coplanar_patches(faces: 'Sequence[int]') -> 'list[tuple[int, ...]]' -- Group a subset of faces into maximal flat, connected patches.

class Vec3(x: 'float' = 0.0, y: 'float' = 0.0, z: 'float' = 0.0) -> None

Vec3(x: 'float' = 0.0, y: 'float' = 0.0, z: 'float' = 0.0)

  • dot(other: 'Vec3') -> 'float'
  • cross(other: 'Vec3') -> 'Vec3'
  • normalized() -> 'Vec3'
  • lerp(other: 'Vec3', t: 'float') -> 'Vec3'
  • min(other: 'Vec3') -> 'Vec3'
  • max(other: 'Vec3') -> 'Vec3'
  • as_tuple() -> 'tuple[float, float, float]'

class Mat4(ax: 'float' = 1.0, bx: 'float' = 0.0, cx: 'float' = 0.0, dx: 'float' = 0.0, ay: 'float' = 0.0, by: 'float' = 1.0, cy: 'float' = 0.0, dy: 'float' = 0.0, az: 'float' = 0.0, bz: 'float' = 0.0, cz: 'float' = 1.0, dz: 'float' = 0.0) -> None

A 3x4 affine map, written as three rows of four.

  • translation(v: 'Vec3') -> 'Mat4'
  • scaling(sx: 'float', sy: 'float | None' = None, sz: 'float | None' = None) -> 'Mat4'
  • rotation(axis: 'Vec3', degrees: 'float') -> 'Mat4' -- Right-handed rotation about an arbitrary axis (Rodrigues).
  • basis(x: 'Vec3', y: 'Vec3', z: 'Vec3', origin: 'Vec3' = Vec3(x=0.0, y=0.0, z=0.0)) -> 'Mat4' -- The map that sends the unit axes onto these three vectors.
  • apply(p: 'Vec3') -> 'Vec3'
  • apply_vector(v: 'Vec3') -> 'Vec3' -- Directions ignore translation.
  • normal_matrix_apply(n: 'Vec3') -> 'Vec3' -- Transform a surface normal.

anchor3d(node: 'Diagram', name: 'str', point: 'Sequence[float] | Sequence[Sequence[float]]', *, pick: 'str' = 'centroid') -> 'Diagram'

Add an anchor at a 3D point, after the fact. Returns the node.

outline_of(part: 'Diagram | Mesh', view: 'View | None' = None, *, crease: 'float' = 30.0, ridges: 'bool' = True, smooth: 'bool | float | None' = None)

A part's projected outline: ((points, closed), ...) in its own frame.

panel_mosaic(layout, panels, *, width, height, gap=4, margin=4, row_weights=None, column_weights=None, titles=None, letters=True, label_size=4, label_gap=2, header_bounds='band')

Build a page from a rectangular matrix of panel names ('.' is empty).

place_in_clear_space(item, *, within, avoid=(), pad=1, clearance=0.5, steps=9)

Place a Diagram inside a Rect, clear of supplied drawing geometry.

hstack(items: 'Iterable[Diagram]', gap: 'Length' = 0.0, align: 'str' = 'center') -> 'Diagram'

Left to right. align is "top"/"n", "center"/"c", "bottom"/"s", "baseline", or "origin" to line up the drawn frames.

vstack(items: 'Iterable[Diagram]', gap: 'Length' = 0.0, align: 'str' = 'center') -> 'Diagram'

Top to bottom. align is "left"/"w", "center"/"c", "right"/"e", or "origin" to line up the drawn frames.

stack(items: 'Iterable[Diagram]', direction: 'Vec2', gap: 'Length' = 0.0, align: 'str' = 'center') -> 'Diagram'

Pack items along direction, each one gap past the last.

grid(items: 'Iterable[Diagram]', cols: 'int | None' = None, rows: 'int | None' = None, gap: 'Length' = 0.0, col_gap: 'Length | None' = None, row_gap: 'Length | None' = None, align: 'str' = 'center', valign: 'str' = 'center') -> 'Diagram'

Arrange items in a row-major grid with shared column widths and row heights.

flow(items: 'Iterable[Diagram]', columns: 'int' = 2, gap: 'Length' = 0.0, col_gap: 'Length | None' = None, align: 'str' = 'left') -> 'Diagram'

Pack items down columns rather than across rows.

overlay(items: 'Iterable[Diagram]', align: 'str' = 'center') -> 'Diagram'

Stack items on top of each other, first one at the bottom.

pad(item: 'Diagram', top: 'Length', right: 'Length | None' = None, bottom: 'Length | None' = None, left: 'Length | None' = None) -> 'Diagram'

Grow the space an item occupies, CSS shorthand order.

frame(content: 'Diagram', pad: 'Length' = 0.0, radius: 'Length | None' = None, shape: 'str' = 'rect', min_width: 'Length | None' = None, min_height: 'Length | None' = None, kind: 'str' = 'frame') -> 'Diagram'

Draw a shape around content, behind it.

spacer(width: 'Length' = 0.0, height: 'Length' = 0.0) -> 'Diagram'

Empty space that is really there: a phantom box, centred on its origin.

beside(a: 'Diagram', b: 'Diagram', direction: 'Vec2', gap: 'Length' = 0.0) -> 'Diagram'

b placed alongside a in direction, centred across the axis.

align_to(item: 'Diagram', anchor: 'str') -> 'Diagram'

Move an item so its named anchor lands on the origin.

fit(build: 'Callable[[float], Diagram]', width: 'Length | None' = None, height: 'Length | None' = None, *, guess: 'float | None' = None, tries: 'int' = 10, tolerance: 'Length' = 0.05, exact: 'bool' = True, with_extras: 'bool' = False)

Call build with sizes until what it returns fits the target.

graph(nodes, edges: 'Iterable' = (), *, layout: 'str' = 'layered', direction: 'str' = 'down', gap: 'Length | None' = None, rank_gap: 'Length | None' = None, lane: 'Length | None' = None, roots: 'Sequence | None' = None, iterations: 'int' = 300, route: 'str' = 'auto', sweeps: 'int' = 4, ports: 'bool' = True, fit: 'Length | None' = None, name: 'str | None' = None) -> 'Graph'

Lay out a graph from its edges, and hand back the diagram and the arrows.

class Graph(diagram: 'Diagram', nodes: 'tuple[Diagram, ...]', edges: 'tuple[GraphEdge, ...]', layout: 'str', ranks: 'tuple[int, ...]', keys: 'Mapping[str, int]' = <factory>) -> None

What inklet.graph() returns: a laid-out diagram plus its edges.

  • add_to(figure, **overrides) -> 'list[Link]' -- Put the graph on a figure and route every edge. The usual spelling.
  • build(*, min_arrow_size=None, min_stroke_width=None) -> 'Diagram' -- Build a self-contained static diagram, including all routed edges.

class GraphEdge(source: 'Diagram', target: 'Diagram', label: 'Diagram | None' = None, route: 'str' = 'straight', span: 'int' = 0, options: 'Mapping[str, object]' = <factory>) -> None

One edge, resolved: the two node diagrams, and how to draw the arrow.

  • link_kwargs() -> 'dict[str, object]' -- Everything but the endpoints, ready to splat into fig.link.

class GraphError

A graph that cannot be laid out as asked.

sankey(flows: 'Iterable[Sequence]', *, nodes: 'Iterable' = (), labels: 'Mapping | Callable[[object], str] | None' = None, length: 'Length | None' = None, breadth: 'Length | None' = None, node_width: 'Length | None' = None, gap: 'Length | None' = None, label_gap: 'Length | None' = None, direction: 'str' = 'right', order: 'str' = 'barycentre', sweeps: 'int' = 4, relax: 'int' = 6, ease: 'float | None' = None, color: 'Mapping | Callable[[object], str] | None' = None, tint: 'str' = 'source', opacity: 'float' = 0.55, halo: 'float | None' = None, name: 'str | None' = None) -> 'Sankey'

Lay out a Sankey from its flows and draw it.

class Sankey(diagram: 'Diagram', nodes: 'tuple[SankeyNode, ...]', flows: 'tuple[SankeyFlow, ...]', crossings: 'int', unit: 'float', keys: 'Mapping[object, int]' = <factory>) -> None

What inklet.sankey() returns: the drawing, and everything it decided.

  • add_to(figure) -> 'Diagram' -- Put the drawing on a figure. Nothing to route: a ribbon is content.
  • node(key) -> 'SankeyNode' -- The full record for a node, rank and value included.

class SankeyError

A flow diagram that cannot be laid out as asked.

class SankeyFlow(source: 'SankeyNode', target: 'SankeyNode', value: 'float', diagram: 'Diagram') -> None

One ribbon, resolved: its two nodes, its value, and the band drawn.

class SankeyNode(key: 'object', label: 'str', rank: 'int', order: 'int', value: 'float', box: 'Rect', diagram: 'Diagram') -> None

One bar: what it is, where the layout put it, and how much goes through.

connect(source: 'Diagram', target: 'Diagram', *, within: 'Diagram | None' = None, **kwargs) -> 'Diagram'

Connect two placed shapes, clipping the ends to their actual boundaries.

Declare a connector. Nothing is measured until route().

class Link(source: 'Diagram | AnchorRef | Sequence[Diagram | AnchorRef]', target: 'Diagram | AnchorRef | Sequence[Diagram | AnchorRef]', through: 'Sequence[Diagram | AnchorRef]' = (), kind: 'str' = 'arrow', route: 'str' = 'straight', label: 'Diagram | None' = None, label_side: 'str' = 'center', label_offset: 'float' = 1.0, standoff: 'float' = 0.0, arrow_size: 'float | None' = None, style: 'Style' = Style(fill=None, stroke=None, stroke_width=None, stroke_dash=None, stroke_linecap=None, stroke_linejoin=None, opacity=None, fill_opacity=None, stroke_opacity=None, corner_radius=None, font_family=None, font_size=None, font_weight=None, font_style=None, text_fill=None, line_height=None, halo=None, halo_color=None), name: 'str | None' = None, head: 'str | None' = None, corner: 'float' = 0.0, shoulder: 'float | None' = None, waypoints: 'Sequence[Vec2 | tuple[float, float] | AnchorRef | tuple[AnchorRef, float, float]]' = (), port: 'float' = 0.0, target_port: 'float' = 0.0, offset: 'float' = 0.0, loop: 'str | None' = None, loop_size: 'float | None' = None, stem: 'float | None' = None) -> None

An arrow that has not been drawn yet.

Turn a spec into geometry: shaft, heads and label, in world coordinates.

Route links in declaration order, reserving each shaft and label.

figure(width: 'float | str' = 89.0, **kwargs) -> 'Figure'

A page to put content on. See Figure for everything it can do.

Figure(width: 'float' = 89.0, height: 'float | None' = None, theme: 'Theme' = , margin: 'float' = 2.0, background: 'str | None' = None, _content: 'list[Diagram]' = , _links: 'list[Link]' = , _built: 'tuple[Diagram, dict[str, Placement]] | None' = None)

  • add(*diagrams: 'Diagram') -> 'Diagram' -- Stack content vertically. Returns the last item for chaining.
  • link(source, target, *, label: 'str | Diagram | None' = None, label_plate: 'bool' = True, **kwargs) -> 'Link' -- Connect two things. The link module works in geometry alone, so a string label is shaped here, where the theme is known.
  • build() -> 'tuple[Diagram, dict[str, Placement]]' -- Lay out the content, route the links over it, put it on the page.
  • page_rect(content_box: 'Rect | None' = None) -> 'Rect' -- The finished page, in millimetres.
  • lint(**kwargs) -> 'list[Diagnostic]' -- Every rule, run over the built figure. See inklet.lint.
  • report(**kwargs) -> 'str' -- Return lint() diagnostics formatted as text.
  • to_svg(*, text: 'str' = 'names', **kwargs) -> 'str' -- The figure as SVG text, page frame and background included.
  • to_pdf(*, text: 'str' = 'outline', **kwargs) -> 'bytes' -- The figure as PDF bytes, on the same page as to_svg puts it.
  • to_png(*, dpi=150, **kwargs) -> 'bytes' -- Render PNG at physical DPI with optional resvg, without a browser.
  • export(directory: 'str | Path', *, name: 'str' = 'figure', dpi: 'float' = 150, text: 'str' = 'embed', compare_pdf: 'bool' = True, png_backend: 'str' = 'resvg', compare_to=None) -> 'dict[str, Path]' -- Write SVG, PDF, PNG, diagnostics and a local HTML review page.
  • save(*paths: 'str | Path', **kwargs) -> 'dict[str, bool]' -- Write the figure to SVG, PDF or PNG, following each filename suffix.

Theming

theme(name: 'str' = 'nature') -> 'Theme'

Look up a theme by name. The default is the one built for print.

A complete set of design tokens.

  • with_palette(palette: "'str | Palette | tuple[str, ...]'") -> "'Theme'" -- This theme with other series colours, given by name, as a Palette or as a sequence of colours: NATURE.with_palette("inklet").
  • style_for(role: 'str') -> 'Style' -- The Style for a semantic role.
  • color(index: 'int') -> 'str' -- The categorical colour for series index.
  • text_on(background: 'str', min_ratio: 'float' = 4.5) -> 'str' -- Ink that stays readable on background.
  • ink_color(index: 'int', min_ratio: 'float' = 3.0) -> 'str' -- color(index), darkened towards ink until it clears min_ratio against paper.
  • text_color(index: 'int', min_ratio: 'float' = 4.5) -> 'str' -- color(index), darkened along its own hue until it can carry text.
  • gap(step: 'int | str') -> 'float' -- A spacing value, by name ('xs' 's' 'm' 'l' 'xl') or by index.
  • scaled(factor: 'float') -> "'Theme'" -- The same design at a different physical size.

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

use_theme(name: 'str | Theme') -> 'Theme'

Set the theme new content is built against.

current_theme() -> 'Theme'

The theme new nodes are being styled with right now.

contrast_ratio(a: 'str | Sequence[float]', b: 'str | Sequence[float]') -> 'float'

WCAG contrast ratio, 1.0 (identical) to 21.0 (black on white).

mix(a: 'str | Sequence[float]', b: 'str | Sequence[float]', t: 'float') -> 'str'

Blend a towards b; t=0 returns a, t=1 returns b.

lighten(color: 'str | Sequence[float]', amount: 'float') -> 'str'

Move amount of the way towards white.

darken(color: 'str | Sequence[float]', amount: 'float') -> 'str'

Move amount of the way towards black.

readable(color: 'str | Sequence[float]', on: 'str | Sequence[float]', min_ratio: 'float' = 4.5) -> 'str'

The nearest colour to color, along its own lightness, that can be read on on.

Inspection and output

class FigureReview(diagram: 'Diagram', findings: 'tuple[Diagnostic, ...]', highlighted: 'int', source: 'Diagram | None' = None) -> None

All findings plus a numbered overlay, without altering the source figure.

  • as_dict() -- JSON-ready findings with stable node references and page coordinates.
  • save(prefix) -- Write a numbered SVG overlay and matching JSON finding list.
  • save_bundle(directory, *, reference=None, sources=(), panels=None, reference_regions=None, dpi=180, caption='Figure comparison') -- Export original art, diagnostics, source hashes and an HTML comparison.

review_figure(art, *, max_highlights=100, **checks)

Run figure checks and return an inspectable numbered diagnostic overlay.

lint(root: 'Diagram', *, page: 'Rect | None' = None, rules: 'Iterable[str] | Mapping[str, Rule] | None' = None, min_font_pt: 'float' = 5.0, min_stroke_mm: 'float' = 0.088, min_dpi: 'float' = 300.0, placements: 'Mapping[str, Placement] | None' = None, page_fill: 'str' = '#ffffff', min_clearance_mm: 'float' = 1.0, min_overlap_fraction: 'float' = 0.08, max_stroke_widths: 'int' = 3, max_font_pt: 'float | None' = None, max_height_mm: 'float | None' = None, max_letter_pt: 'float | None' = None, expected_fonts: 'Sequence[str] | None' = None, expect: 'Iterable[str]' = (), house: 'HouseRules | None' = None) -> 'list[Diagnostic]'

Check a figure and return its diagnostics, deterministically ordered.

abutting(kind: 'str' = 'group') -> 'str'

Declare that the parts inside this subtree touch by design.

crossing(stroke: "'Diagram'", *through: "'Diagram'") -> "'Diagram'"

Declare that stroke is drawn through through on purpose.

class Diagnostic(code: 'str', severity: 'str', message: 'str', targets: 'tuple[str, ...]', where: 'Rect | Vec2 | None', hint: 'str | None' = None) -> None

One actionable finding. where is figure-space, in millimetres.

format_report(diags: 'Sequence[Diagnostic]', *, color: 'bool' = False) -> 'str'

Compact report. Returns a single string with no trailing newline.

to_svg(root: 'Diagram | RenderScene', *, width: 'float | str | None' = None, height: 'float | str | None' = None, margin: 'float' = 0.0, background: 'str | None' = None, precision: 'int' = 3, title: 'str | None' = None, compact: 'bool | str' = 'auto', text: 'str' = 'names', ids: 'str' = 'nodes') -> 'str'

Render a diagram tree to a self-contained SVG document.

save_svg(root: 'Diagram | RenderScene', path: 'str', *, width: 'float | str | None' = None, height: 'float | str | None' = None, margin: 'float' = 0.0, background: 'str | None' = None, precision: 'int' = 3, title: 'str | None' = None, compact: 'bool | str' = 'auto', text: 'str' = 'names', ids: 'str' = 'nodes') -> 'None'

Write root to path as SVG. to_svg is the same thing as a string.

to_pdf(root: 'Diagram | RenderScene | Sequence[Diagram | RenderScene]', *, width: 'float | str | None' = None, height: 'float | str | None' = None, margin: 'float' = 0.0, background: 'str | None' = None, precision: 'int' = 3, title: 'str | None' = None, compress: 'bool' = True, text: 'str' = 'outline') -> 'bytes'

Render one diagram tree, or a sequence of them, to a PDF document.

save_pdf(root: 'Diagram | RenderScene | Sequence[Diagram | RenderScene]', path: 'str | Path', **kwargs) -> 'None'

Write root to path as PDF. to_pdf is the same thing as bytes.

outline_text(root: 'Diagram') -> 'Diagram'

Return root with every shaped text block replaced by its glyph outlines.

shape(text: 'str', *, font: 'str | FontFace' = 'sans', size: 'float | str' = 2.469444444444444, weight: 'str' = 'regular', align: 'str' = 'center', line_height: 'float' = 1.25, width: 'float | str | None' = None, features: 'dict[str, bool | int] | None' = None, markup: 'bool' = True, colors: 'Mapping[str, str] | None' = None) -> 'TextPrim'

Measure a string into a fully-shaped TextPrim.

measure(text: 'str', **options) -> 'Rect'

The block's local bounding box, centred on the origin like the prim itself.

apply_theme(root: 'Diagram', theme: 'Theme') -> 'Diagram'

Slide theme styles underneath whatever the author set explicitly.

resolve(root: 'Diagram', base: 'Affine' = Affine(a=1.0, b=0.0, c=0.0, d=1.0, e=0.0, f=0.0), base_style: 'Style' = Style(fill=None, stroke=None, stroke_width=None, stroke_dash=None, stroke_linecap=None, stroke_linejoin=None, opacity=None, fill_opacity=None, stroke_opacity=None, corner_radius=None, font_family=None, font_size=None, font_weight=None, font_style=None, text_fill=None, line_height=None, halo=None, halo_color=None)) -> 'dict[str, Placement]'

Flatten the tree into world transforms, keyed by node id.

Core types and units

class Diagram(prim: 'Prim | None' = None, children: "tuple['Diagram', ...]" = (), transform: 'Affine' = Affine(a=1.0, b=0.0, c=0.0, d=1.0, e=0.0, f=0.0), style: 'Style' = Style(fill=None, stroke=None, stroke_width=None, stroke_dash=None, stroke_linecap=None, stroke_linejoin=None, opacity=None, fill_opacity=None, stroke_opacity=None, corner_radius=None, font_family=None, font_size=None, font_weight=None, font_style=None, text_fill=None, line_height=None, halo=None, halo_color=None), kind: 'str' = 'g', name: 'str | None' = None, id: 'str' = '', envelope_override: 'Envelope | None' = None, attached_to: 'tuple[str, ...]' = (), anchors: 'dict[str, Vec2]' = <factory>, notes: 'dict[str, object]' = <factory>, clip_region: 'tuple[Vec2, ...]' = (), _cache: 'dict' = <factory>) -> None

Diagram(prim: 'Prim | None' = None, children: "tuple['Diagram', ...]" = (), transform: 'Affine' = Affine(a=1.0, b=0.0, c=0.0, d=1.0, e=0.0, f=0.0), style: 'Style' = Style(fill=None, stroke=None, stroke_width=None, stroke_dash=None, stroke_linecap=None, stroke_linejoin=None, opacity=None, fill_opacity=None, stroke_opacity=None, corner_radius=None, font_family=None, font_size=None, font_weight=None, font_style=None, text_fill=None, line_height=None, halo=None, halo_color=None), kind: 'str' = 'g', name: 'str | None' = None, id: 'str' = '', envelope_override: 'Envelope | None' = None, attached_to: 'tuple[str, ...]' = (), anchors: 'dict[str, Vec2]' = , notes: 'dict[str, object]' = , clip_region: 'tuple[Vec2, ...]' = (), _cache: 'dict' = )

  • extent(direction: 'Vec2') -> 'float' -- How far this reaches along a direction, in the parent's frame. This is what stacking asks, and why a rotated shape packs tighter than its bbox.
  • anchor(name: 'str', at: 'tuple[float, float] | Vec2') -> "'Diagram'" -- Register a named point. A tuple is read as fractions of the local bounding box, (0, 0) being its top-left corner -- the natural way to point at an ear in a photograph.
  • anchor_point(name: 'str' = 'center') -> 'Vec2' -- Local coordinates of a named or compass anchor.
  • registered_point(name: 'str') -> 'Vec2 | None' -- A registered anchor's coordinates in this node's frame, or None.
  • note(key: 'str', value: 'object') -> "'Diagram'" -- Record something about this node that core has no opinion on.
  • carry_notes(source: "'Diagram'") -> "'Diagram'" -- Copy source's notes onto this node, re-expressed in this frame.
  • at(name: 'str') -> "'AnchorRef'"
  • placed(transform: 'Affine') -> "'Diagram'" -- Wrap in a positioned parent, leaving this node untouched so callers keep a working handle on it.
  • translated(dx: 'float', dy: 'float' = 0.0) -> "'Diagram'"
  • rotated(degrees: 'float') -> "'Diagram'"
  • scaled(factor: 'float', factor_y: 'float | None' = None) -> "'Diagram'"
  • centered() -> "'Diagram'" -- Shift so the envelope's centre sits on the origin.
  • styled(**kwargs) -> "'Diagram'"
  • named(name: 'str') -> "'Diagram'"
  • copy() -> "'Diagram'" -- Fresh identities throughout, for placing the same shape twice.
  • walk() -> "Iterator['Diagram']"
  • find(name: 'str') -> "'Diagram'"

class DiagramError

Common base class for all non-exit exceptions.

class Style(fill: 'str | None' = None, stroke: 'str | None' = None, stroke_width: 'float | None' = None, stroke_dash: 'tuple[float, ...] | None' = None, stroke_linecap: 'str | None' = None, stroke_linejoin: 'str | None' = None, opacity: 'float | None' = None, fill_opacity: 'float | None' = None, stroke_opacity: 'float | None' = None, corner_radius: 'float | None' = None, font_family: 'str | None' = None, font_size: 'float | None' = None, font_weight: 'str | None' = None, font_style: 'str | None' = None, text_fill: 'str | None' = None, line_height: 'float | None' = None, halo: 'float | None' = None, halo_color: 'str | None' = None) -> None

Style(fill: 'str | None' = None, stroke: 'str | None' = None, stroke_width: 'float | None' = None, stroke_dash: 'tuple[float, ...] | None' = None, stroke_linecap: 'str | None' = None, stroke_linejoin: 'str | None' = None, opacity: 'float | None' = None, fill_opacity: 'float | None' = None, stroke_opacity: 'float | None' = None, corner_radius: 'float | None' = None, font_family: 'str | None' = None, font_size: 'float | None' = None, font_weight: 'str | None' = None, font_style: 'str | None' = None, text_fill: 'str | None' = None, line_height: 'float | None' = None, halo: 'float | None' = None, halo_color: 'str | None' = None)

  • over(base: 'Style | None') -> 'Style' -- Resolve self against an inherited style, self winning where set.
  • with_(**kwargs) -> 'Style'

class StyleError

Inappropriate argument value (of correct type).

class Vec2(x: 'float' = 0.0, y: 'float' = 0.0) -> None

Vec2(x: 'float' = 0.0, y: 'float' = 0.0)

  • dot(other: 'Vec2') -> 'float'
  • cross(other: 'Vec2') -> 'float'
  • normalized() -> 'Vec2'
  • perp() -> 'Vec2' -- Rotated a quarter turn. Used for arrow heads and label offsets.
  • angle() -> 'float'

class Rect(x0: 'float', y0: 'float', x1: 'float', y1: 'float') -> None

Rect(x0: 'float', y0: 'float', x1: 'float', y1: 'float')

  • from_size(width: 'float', height: 'float', center: 'Vec2' = Vec2(x=0.0, y=0.0)) -> 'Rect'
  • hull(points) -> 'Rect'
  • union(other: 'Rect') -> 'Rect'
  • pad(top: 'float', right: 'float | None' = None, bottom: 'float | None' = None, left: 'float | None' = None) -> 'Rect' -- CSS shorthand order.
  • overlap(other: 'Rect') -> 'Rect | None'
  • contains(p: 'Vec2') -> 'bool'
  • transform(t: 'Affine') -> 'Rect' -- Exact axis-aligned bounds of this rectangle after an affine map.

class Affine(a: 'float' = 1.0, b: 'float' = 0.0, c: 'float' = 0.0, d: 'float' = 1.0, e: 'float' = 0.0, f: 'float' = 0.0) -> None

SVG's matrix(a b c d e f): x' = ax + cy + e, y' = bx + dy + f.

  • translation(dx: 'float', dy: 'float') -> 'Affine'
  • scaling(sx: 'float', sy: 'float | None' = None) -> 'Affine'
  • rotation(degrees: 'float') -> 'Affine'
  • apply(p: 'Vec2') -> 'Vec2'
  • apply_vector(v: 'Vec2') -> 'Vec2' -- Directions ignore translation.
  • transpose_linear(v: 'Vec2') -> 'Vec2' -- Apply the transpose of the linear part. This is what pulls a query direction back through a transform when evaluating an envelope.
  • inverse() -> 'Affine'
  • uniform_scale() -> 'float' -- Return the geometric mean scale factor.

mm(value: 'float | int | str') -> 'float'

Coerce a length to millimetres. Bare numbers are already mm.

pt(value: 'float') -> 'float'

Points to millimetres, for font sizes and hairline strokes.

COLUMN_SINGLE = 89.0

Numeric constant.

COLUMN_DOUBLE = 183.0

Numeric constant.

Stable subpackages

These packages are covered by the same compatibility policy as top-level inklet. Before 4.3 they lived under inklet.experimental; those paths still work and return the same objects (see migration).

inklet.volume

Calibrated microscopy volumes, sections, slabs, channels and measurements.

class Volume(data: object, spacing_zyx: tuple[float, float, float], unit: str, origin_xyz: tuple[float, float, float] = (0.0, 0.0, 0.0), source_id: str = '') -> None

An immutable scalar snapshot with explicit voxel calibration and identity.

  • world(index_zyx) -- Convert a finite fractional voxel index to a physical X,Y,Z position.
  • report()
  • slice(axis, index) -- An axis-aligned physical section, with the second axis pointing up.
  • crop(start_zyx, stop_zyx) -- Half-open voxel bounds; preserve the original physical coordinate frame.
  • reslice(plane, *, kind) -- Sample an explicit physical plane: linear intensities or nearest labels.
  • project_slab(slab, *, reduction, region=None) -- Project physical intensity samples, optionally restricted to a shared region.
  • measure(label) -- Voxel-count volume, centroid and boundary status of one integer label.
  • surface(label, *, allow_clipped=False, step_size=1) -- Marching-cubes surface of one label, in calibrated world coordinates.

class Slice(volume: inklet.volume._volume.Volume, axis: str, index: int) -> None

Slice(volume: inklet.volume._volume.Volume, axis: str, index: int)

  • project(world_xyz, *, width) -- Image-centred mm (+y down); accepts points in this voxel slab only.
  • diagram(*, width, window) -- A greyscale slice with an explicit shared display window and no resampling.
  • scalebar(length, *, width) -- A separate vector key; place beside the image without further scaling.

class Plane(centre_xyz: tuple[float, float, float], right_xyz: tuple[float, float, float], up_xyz: tuple[float, float, float], shape_yx: tuple[int, int], spacing_yx: tuple[float, float], unit: str) -> None

A rectangular sampling plane; output rows run downward, columns rightward.

  • world(row, column) -- Physical XYZ for a fractional output pixel index; index 0 is a centre.
  • project(world_xyz, *, width) -- Project an on-plane point to image-centred page mm, with +y downward.
  • scalebar(length, *, width) -- A separate vector key in physical units; scale together with the image.
  • report()

class SampledSection(plane: inklet.volume._sections.Plane, volume: inklet.volume._volume.Volume, kind: str, data: object, valid: object) -> None

An immutable resampled array plus an explicit source-coverage mask.

  • report()
  • contours(label) -- Exact sampled-label pixel edges, with source-coverage limits kept separate.
  • measure(label) -- Sampled label area, not 3D volume or a native-resolution measurement.
  • diagram(*, width, window) -- Windowed greyscale RGBA image; out-of-volume samples are transparent.

reslice(volume, plane, *, kind)

Resample a plane; labels preserve exact integer IDs, including uint64.

class Slab(plane: inklet.volume._sections.Plane, thickness: float, samples: int) -> None

A finite thickness about a Plane, sampled at equal-width bin midpoints.

  • face(offset) -- A parallel plane at a signed physical distance along the normal.
  • report()

class SlabProjection(slab: inklet.volume._slabs.Slab, volume: inklet.volume._volume.Volume, reduction: str, data: object, counts: object, region: inklet.volume._regions.BoxRegion | None = None) -> None

Immutable intensity projection and count of contributing samples at each pixel.

  • report()
  • diagram(*, width, window) -- Windowed image; pixels with no contributing samples are transparent.

project_slab(volume, slab, *, reduction, region=None)

Reduce intensity samples with O(output pixels) working memory.

class BoxRegion(selection_id: str, lower_xyz: tuple[float, float, float], upper_xyz: tuple[float, float, float], unit: str) -> None

An axis-aligned world XYZ box with a stable, caller-assigned identity.

  • report()
  • mask(plane) -- Immutable YX membership of section pixel centres, independent of source coverage.
  • intersection(plane) -- World XYZ polygon of box/plane intersection, clipped to the image extent.
  • outline(plane, *, width, **style) -- Vector outline in the same image-centred page coordinates as Plane.project.
  • measure(volume, *, label) -- Count an exact integer label within the box on the supplied source grid.

class Channel(name: str, sampled: inklet.volume._sections.SampledSection | inklet.volume._slabs.SlabProjection, color: str, window: tuple[float, float], weight: float = 1.0) -> None

One sampled intensity signal and its explicit display mapping.

  • report()

class Composite(channels: tuple[inklet.volume._channels.Channel, ...], coverage: str) -> None

Additive display RGB from channels sharing exactly the same sampling geometry.

  • report()
  • diagram(*, width)
  • legend(*, size=2.822222222222222) -- Vector color keys recording channel names, windows and display weights.

class LabelContour(section: inklet.volume._sections.SampledSection, label: int) -> None

Boundary segments of one exact label ID on a sampled section grid.

  • report()
  • world_segments(*, include_coverage=False) -- Physical XYZ edge pairs for use with saved-camera vector paths.
  • diagram(*, width, stroke, stroke_width=0.25, coverage='omit') -- Vector boundaries aligned with the section image; coverage edges are explicit.

class LabelMeasurements(_payload: str) -> None

A reproducible long-form table; report and row access return fresh copies.

  • report()
  • to_json()
  • to_csv() -- Long-form CSV; retain label_id as text when importing large IDs.

measure_labels(labels, channels, *, label_ids=None, region=None, coverage='intersection')

Measure source intensities without display windows, weights or RGB conversion.

class TiffImage(names: tuple[str, ...], volumes: tuple[inklet.volume._volume.Volume, ...], _provenance: str) -> None

Named immutable scalar volumes plus import provenance.

  • report()

read_tiff(path, *, spacing_zyx, unit, source_id, channel_names=None, origin_xyz=(0.0, 0.0, 0.0), series=0, time_index=None, axes=None)

Read a calibrated ZYX volume per channel from a local TIFF series.

inklet.selection

Immutable keyed tables and portable selection states.

class KeyedTable(name, columns, *, key='id')

Snapshot scalar columns with a stable table name and unique string key.

  • from_pandas(name, frame, *, key='id', columns=None, time_columns=None) -- Snapshot a pandas DataFrame; ignore its index and require a string key.
  • from_polars(name, frame, *, key='id', columns=None, time_columns=None) -- Snapshot an eager Polars DataFrame with an explicit string key.
  • subset(ids) -- Return columns in source order, rejecting IDs absent from this table.

class SelectionState(table: 'str', data_digest: 'str', selected_ids: 'tuple[str, ...]' = (), visible_ids: 'tuple[str, ...] | None' = None) -> None

A selection and optional visibility filter tied to exact table contents.

  • for_table(table, *, selected=(), visible=None)
  • validate(table)
  • visible(table)
  • rebase(table, *, missing='error') -- Bind to revised contents; report removed IDs when explicitly dropping.
  • to_json()
  • from_json(payload)

class RebasedSelection(state: 'SelectionState', removed_selected: 'tuple[str, ...]', removed_visible: 'tuple[str, ...]') -> None

The result of SelectionState.rebase: the rebound state and dropped IDs.

inklet.project

Reproducible figure projects with verified assets and explicit correspondence.

class Asset(id: str, path: str, sha256: str, size: int, source: str, license: str, role: str = 'data', unit: str | None = None) -> None

One source file with author-supplied provenance and optional physical units.

class AssetManifest(assets: tuple[inklet.project.assets.Asset, ...] = ()) -> None

Immutable inventory. Capture explicitly chosen files; verify before reuse.

  • capture(root, entries) -- Capture dictionaries with id/path/source/license and optional role/unit.
  • verify(root) -- Return verified file paths by asset ID; reject missing or changed bytes.
  • to_dict()
  • from_dict(value)

class EntityMap(entities=(), sources=None)

An immutable entity registry with source-local, many-to-one bindings.

  • selected(source, local_ids) -- Translate a source selection to canonical entity IDs.
  • targets(entities) -- Translate canonical selection to every mapped content source.
  • selection_for(source, table, entities) -- Bind selection to an existing table with source-local keys.
  • validate_source(source, local_ids) -- Require exact coverage, including IDs which are currently unselected.
  • view(source, table, view) -- Map a source-native drawing/image/field view into the linked runtime.
  • joined_table(name, tables) -- Join keyed tables by explicit entities for the existing linked runtime.
  • changes(revised) -- Report removed entities and every removed or reassigned local binding.
  • to_dict()
  • from_dict(value)

class ExportDriftWarning

A reopened project's SVG differs from the export recorded when it was saved.

class FigureProject(name, recipe, *, assets=None, identities=None, selected=(), width=None, height=None, preset=None)

Connect a Composition editor, an asset inventory and entity selection.

  • select(source, local_ids) -- Select through any registered content source; return all linked targets.
  • state_for(figure) -- Apply canonical selection to a BrowserFigure built from joined_table().
  • select_state(figure, state) -- Transfer a validated linked-view selection back into the project.
  • save(directory, *, asset_root) -- Stage a new portable directory with verified assets and SVG/PDF exports.
  • open(directory, factory, *, verify_export=True) -- Verify the bundle, then call trusted factory(root) to rebuild its recipe.
  • revise(recipe, *, assets=None, identities=None, missing='error') -- Return a new project, preserving valid choices and reporting conflicts.

inklet.editor

Local browser editing of composition layouts, labels, styles and cameras through Python.

class LayoutEditor(recipe, *, width=None, height=None, preset=None)

Edit a live Composition layout, labels, styles and cameras with matching Python exports.

  • overrides() -- Return independently owned JSON-compatible saved layout choices.
  • snapshot() -- Return current controls, revision and preview without rebuilding.
  • command(action, value=None, *, revision=None, missing='error') -- Compile a command atomically; a stale revision or failed build changes nothing.
  • start(*, port=0) -- Start a loopback-only editor server; port=0 chooses a free local port.
  • close() -- Stop the local server; compiled output and saved choices remain accessible.

Diagnostic codes

Diagnostic codes returned by fig.lint() and formatted by fig.report(). Review each finding in the context of the finished figure; passing diagnostics does not replace visual or scientific review.

fig.lint() takes the thresholds as keywords: min_font_pt, min_clearance_mm, max_stroke_widths, min_contrast, min_dpi. fig.report() takes the same ones and formats the result.

AXIS_TITLE_OVERHANG

A plot's y-axis title longer than the plot, and what it runs into.

BAR_WIDTH_OUT_OF_SCALE

Bars whose width in data units is wider than the axis they stand on.

BOLD_TEXT

Bold anywhere but a panel letter.

BREAK_DISTORTS

Report marks compared across a broken axis and the scale distortion.

COINCIDENT_SHAFT

Two links drawn along the same line, one hidden under the other.

CROWDING

Neighbours that clear each other but only just.

DATA_CLIPPED

Named series whose points clip=True hid from the axes, counted.

DATA_OUTSIDE

Data drawn past the axes of its panel: a range narrower than the data.

DEPTH_ORDER

Report a scene part drawn over another part that is geometrically in front of it.

DUPLICATE_KEY

Two colour bars, or two legends, in one panel for the same series.

EMPTY_DIAGRAM

Nodes that draw nothing, and figures that draw nothing at all.

FONT_SUBSTITUTED

Report text shaped with a font different from the requested font.

HAIRLINE

Strokes that vanish on press. 0.088mm is the usual 0.25pt floor.

INCONSISTENT_STROKE

Report more distinct line weights than the configured limit.

KEY_COVERS_DATA

A key inside the plot area painted over the panel's own data.

KEY_IN_PANEL

A key drawn as part of a plot panel rather than outside every panel.

KEY_MISMATCH

Report a color key that does not match the adjacent marks.

LABEL_COVERS_SHAFT

A link's own label plate drawn over its own elbow.

A link label that found no room beside its link and was moved away.

LABEL_UNPLACED

Labels a placer reported it could not place without a collision.

LARGE_TEXT

Text above an optional publication maximum after enclosing transforms.

An arrow the author asked for that is not on the page.

A connector running straight through a shape it was not routed to.

Two connectors that cross each other.

Report an arrow whose endpoint does not meet the target boundary.

LOW_CONTRAST

Text that does not separate from what is behind it.

LOW_DPI

Rasters placed larger than their pixels support.

MARKER_CUT

Markers the axes edge cuts through, which clip=True leaves half drawn.

MARKER_OUTLINE

A filled marker with an outline in another colour.

MISSING_GLYPHS

Text no installed font can draw, which prints as a row of empty boxes.

MUTED_TEXT

Text in a grey lighter than ink, or in a colour the house calls muted.

OFF_CANVAS

Anything drawable that leaves the page.

OFF_PANEL

Text that leaves the plot box of the panel it was placed in.

ORPHAN_LEADER

Leaders drawn to a label with no text in it.

OVERLAP

Colliding elements, filtered hard against false positives.

PAGE_TOO_TALL

Page height above an optional publication limit, in physical millimetres.

PATH_CROSSES

A stroke that is not a routed link running through a drawing.

PLOT_WIDTH_OVERRIDDEN

A plot drawn much narrower than the width its author set.

ROUTE_BLOCKED

A link that asked to go around the obstacles and could not.

ROWS_COMBINED

Bars that summed repeated rows, and lines that zigzag through them.

SERIES_FLATTENED

A named series squashed flat by a much taller one on the same axis.

STROKE_TIER

An author's stroke in a plot panel at a width the house does not use.

TEXT_FILL_IGNORED

fill= on a text node, where the glyph colour is text_fill=.

TEXT_OVERFLOW

A label wider or taller than the box it was put inside.

TEX_MATH

LaTeX written into a label, which inklet prints literally.

TICKS_DROPPED

Explicitly supplied ticks an axis left out for lack of room.

TINY_TEXT

Type below the legibility floor once every enclosing scale is applied.

Search documentation

Type to search guides, examples and the API.