annotation_strip
Trees & flows
Minimal call
cols = [f"c{i}" for i in range(10)]
groups = {"col": cols, "group": ["A"] * 3 + ["B"] * 4 + ["C"] * 3}
bars = {"col": cols, "v": [3, 5, 4, 6, 7, 5, 6, 4, 3, 5]}
strip = pt.chart(groups, aes(position="col", value="group"),
data_height=16)
strip.add_annotation_strip(name="group")
c = pt.chart(bars, aes(x="col", y="v"), data_height=110)
c.add_bar(fill="#8a8fb0")
c.attach_above(strip)
Docstring
Custom artist: annotation strip.
A row or column of cells encoding one value per position (band mode) or
per contiguous run of equal values (block mode). The default is
horizontal (positions along the x axis), designed to align with a host
panel above or below via `share_x` — sample-group bars on top of a
heatmap, regime tags above a time series, cluster labels alongside a
dendrogram, score tracks aligned with a coverage plot, group titles
above a split heatmap, etc. Pass `orientation="y"` for a vertical column.
Each cell can carry any combination of fill, text, and border:
- **Fill** (categorical via `palette={...}`, continuous via `cmap=...`,
or one constant color via `fill=` — the literal-color form, like
`bar`'s `fill="C0"`). `palette` falls back to `fill` for values it
doesn't list; with no fill source at all, cells draw no rect (text /
border only). cmap is band-mode only — per-block cmap aggregates
would mask within-block variation.
- **Text** (`text=True` shows the value; `aes(text="other_col")` pulls
display text from a different column). Position+rotation controlled
by `side=`, `rotation=`, `fontsize=`, `text_color=`, `text_pad=`.
- **Border** (`cell_border="#999"` or `{"color":..., "width":...}`).
In block mode with text only, the border outlines each block.
Three input shapes for the position axis:
- **Categorical** (heatmap-style): map `aes(position=...)` to a column
of category names; cell width comes from the category scale's bandwidth.
- **Numeric uniform** (time-series-style): map `aes(position=...)` to a
numeric column and set `width=` (scalar) in data units of the position
axis.
- **Numeric interval** (cytoband / sector / gene-track style): map
`aes(x1=..., x2=...)` instead of `position`. Each row's cell spans
``[x1, x2]`` — variable widths.
API examples:
# categorical color bar
c.add_annotation_strip(df, aes(position="col", value="col"),
palette={...}, name="Group")
# continuous score bar (band mode only)
c.add_annotation_strip(df, aes(position="col", value="col"),
cmap="viridis", name="Score")
# per-position text labels
c.add_annotation_strip(df, aes(position="col", value="col"),
text=True, side="bottom", rotation=90)
# decorative single-color strip with one legend entry
c.add_annotation_strip(df, aes(position="col", value="col"),
fill="#8da0cb", label="track")
# per-block group titles with fill + text + border
c.add_annotation_strip(df, aes(position="col", value="group"),
mode="block", palette={...}, text=True,
cell_border="#000", text_color="white")
# variable-width interval strip (cytobands, sector bars, gene tracks)
c.add_annotation_strip(df, aes(x1="start", x2="end", value="stain"),
palette={...}, text=True)
`None` / `""` (or NaN in cmap mode) means missing data — drawn as
`absent_fill` if set, otherwise transparent.
In block mode, runs are computed per-contiguous-value (not per unique
value): `[A, B, A, B]` produces four blocks, each rendered with its own
label/fill. Pair with `c.sectors({cluster: [members]}, axis=...)` on the
host heatmap so the cluster machinery groups equal values into single
runs.