group
Partitions the data by a field and wraps each partition in its own frame, without positioning the frames. Pair it with another operator — or a nested mark — to lay the groups out.
from gofish import chart, spread, group, stack, rect
chart(seafood, axes=True).flow(
spread(by="lake", dir="x"),
group(by="species"),
).mark(rect(h="count", fill="species")).render(w=400, h=300)Signature
group(*, by, **options) -> OperatorParameters
Partition rows by by into a flat Frame (no layout beyond grouping).
| Option | Type | Default | Description |
|---|---|---|---|
by | str | Any | Required. Field to group rows by; also accepts a field(...) accessor carrying domain ops (sort/reverse/bin). |
For the simple case — one ribbon or stream band per group, re-partitioning the marks a chart already drew — reach for a bare .layer(ribbon(...)) instead, with no by at all: a ribbon or line fused over a chart's own flow splits at the flow's own grouping by default (see ribbon's Default grouping). group() is for nested splits (composing with a connector's own by, or an explicit by override) and for operator pipelines generally — anywhere you need a named per-partition frame without a connector mark driving the partitioning. group's own by reads refs when it runs after a select_all, and a ref is read through its rows, so the bare field name works — by="species":
chart(select_all("bars")) \
.flow(group(by="species")) \
.mark(ribbon(opacity=0.8))On a ref, a field resolves to a scalar only when every row in the ref's bag agrees on that field (homogeneity collapse); otherwise it is None. See spread → path-aware by for the full explanation.
Returns an Operator for use inside .flow().
How it works
group only partitions — it draws each partition's contents in a shared frame but does not move the frames apart. Use it when a later operator (or the mark itself) is responsible for layout, or when you need the grouping boundary for scales and color.
