On this page
Historical material
This page preserves an earlier release or study. See the current guide for supported behavior.
Inklet v2¶
For nested layouts, publication presets and revision comparison, see the v2.5 guide.
V2 retains authoring instructions until compilation. A Document owns the page
and theme; PlotSpec and ComponentSpec describe its contents. Compilation
measures text and plot furniture, allocates cells, rebuilds plots at their final
size, routes connections and resolves paint for SVG and PDF.
The existing Diagram, Panel and Figure APIs remain supported. Use them for
fixed drawings, or place their output inside a document.
See diagrams for measured architecture modules,
live data for filtered plots and derive() transformations, and
release checks for reproducible validation.
A live plot¶
import inklet as i
data = i.dataset(
{'time': [0, 1, 2], 'signal': [1, 3, 2]},
units={'time': 's', 'signal': 'mV'},
source=i.Source('Demonstration', method='simulated'),
)
p = i.plot_spec(x=(0, 2), y=i.shared_scale(data.column('signal')))
p.legend(side='bottom') # Can be declared before the series.
p.axes(x='Time / s', y='Signal / mV', key='axes')
p.series(i.Series('Signal', data.column('time'), data.column('signal'), '#367ca4'))
doc = i.document(width=100)
doc.add('response', p, min_height=45)
first = doc.compile()
data.update(signal=[1, 3, 8])
p.replace('axes', x='Elapsed time / s', y='Measured signal / mV')
second = doc.compile()
second.export('out/review', name='response')
The second compilation uses the revised data and labels. first remains a
snapshot of the earlier figure. Repeating doc.compile() without changes
returns the same snapshot. Unchanged component geometry is reused when another
cell changes.
Plot methods record their arguments. In 2.5, marks are built first, followed by
axes, legends and colour bars, group labels and insets, brackets, callouts, and titles.
Declaration order is preserved within each phase. key= names an instruction
for replace() or remove(); it is not a drawing style. configure() changes
plot scales, clipping and default dimensions. twin_x() and twin_y() return
live instruction handles for the secondary axes.
Page layout¶
columns=2 creates two equally weighted tracks. columns=[1, 2] requests a
1:2 width allocation, adjusted as necessary to meet cell minima. Place cells
with zero-based row and column; use rowspan and colspan to span tracks.
Omitting row appends below the existing cells.
doc = i.document(width=180, columns=2, gap=6, margin=4)
doc.add('left', left_plot, row=0, column=0, min_width=60, min_height=45)
doc.add('right', right_plot, row=0, column=1, min_width=60, min_height=45)
doc.add('caption', caption_component, row=1, colspan=2, min_height=10)
The page width is fixed. With no page height, rows grow to fit their measured
contents and minima. A fixed page height distributes available space across
rows. Plot areas resize while text and strokes retain their physical sizes.
Plots sharing a row or column share the relevant furniture margins. Existing
Diagram and Panel inputs keep their authored dimensions.
Overlapping cells and unsatisfiable size constraints raise LayoutError with
the available and required dimensions. Inklet does not shrink text or silently
crop content to fit. Data outside a plot's domain is clipped only when you ask
for clip=True, including in inset definitions.
Use doc.configure(width=150, theme='slides') to revise the page, and
doc.replace('caption', new_component) to replace a cell while retaining its
layout constraints. A radically narrower page may require changing the layout
or reducing the number of columns; automatic editorial rearrangement is not
part of the layout contract.
Components and connections¶
db = i.component(i.database, 'Sequence database', width=30)
matrix = i.component(i.feature_matrix, [[0.2, 0.8], [0.7, 0.1]], cell=6)
doc = i.document(width=120, columns=2)
doc.add('database', db, row=0, min_height=30)
doc.add('matrix', matrix, row=0, column=1, min_height=30)
doc.link('database:output', 'matrix:row-0')
Factories run under the document's theme. component.configure(...) revises
arguments. Pass changing inputs explicitly: variables captured inside a Python
closure are not tracked. Ordinary lists and dictionaries are snapshotted when
recorded; Dataset, data references and other specs are live dependencies.
For file-backed assets, pass i.FileRef(path) to the factory so a content change
invalidates its cached drawing.
With responsive=True, a factory receives width and height keywords for
its available cell. During natural-height measurement, height may be None.
The factory must return a measurable Diagram. Repeated uses of the same
component receive independent drawing identities. Link endpoints are cell
names or cell:anchor strings; they resolve after layout.
Shared data definitions¶
Dataset.update() validates all changed columns together before applying an
edit. Columns retain equal lengths, and a failed edit leaves the table intact.
Use column(name) for one column and points(x, y) for paired coordinates.
shared_scale() computes a domain across one or more live numeric columns.
The columns must have matching units and finite values. Linear and logarithmic
scales are supported. Convert incompatible units explicitly before sharing a
scale. Series supplies a name, colour, x/y values and optional absolute
lower/upper uncertainty bounds; it draws a matching legend entry.
CategoryEncoding makes category selection live:
encoding = i.CategoryEncoding(i.categories(
{'a': '#527da8', 'b': '#cb7853'},
labels={'a': 'Control', 'b': 'Treatment'},
))
p = i.plot_spec(x=(0, 10), y=encoding.scale(reverse=True))
p.bars(data.column('condition'), data.column('value'),
orient='h', bar_colors=encoding)
# Update the data and selection together before compiling.
encoding.select(['b'])
Axes, bar colours, keys and p.group_labels(encoding, ...) use the same
selection. Unknown categories fail rather than silently receiving new colours.
Source records a citation and one of measured, digitized, simulated or
illustrative. An optional source file is hashed when the record is created.
The export manifest records data hashes, row counts, units, source records,
font hashes, named cell bounds and compilation statistics. This records how a
figure was made; it does not verify the scientific validity of the source.
Build and review¶
An author script should define make_document() and return a document. Scripts
returning a Figure from make_figure() also work.
python -m inklet doctor
python -m inklet build examples/v2_document.py --output out/review
python -m inklet watch examples/v2_document.py --output out/review
The installed inklet command is equivalent to python -m inklet. doctor
reports optional preview dependencies. Use build --vectors-only when Chrome
and Poppler are unavailable, or --no-pdf-preview to omit the independent PDF
preview. PNG output requires Pillow and Chrome/Chromium; PDF previews require
Poppler.
watch serves on localhost and rebuilds in a fresh Python process when author
code changes. Add --watch data.csv or --watch assets/ for data and assets.
The previous successful bundle remains visible after a failed build; the page
shows the error and resumes after the next successful edit. Use Ctrl-C to stop.
The review page includes SVG/PDF previews, the editable SVG and clickable spatial diagnostics. Clicking a finding opens and highlights its figure region. JSON diagnostics and the manifest are available alongside the exports.
See the complete live example, benchmark figures, and export options.