render_layers
Mojo function 🡭
render_layers
fn def render_layers(plots: List[AnyChart]) -> CanvasRender every Plot in plots onto one shared coordinate system: one combined x/y domain across every layer, one set of axes/gridlines/ ticks, each mark drawn over the last in the order given.
Takes the marks that place their data on a continuous x/y axis in the
caller’s own units, which is what one shared domain can mean:
Mark.POINT, LINE, AREA, EFFECT_SCATTER, KDE, RUG,
BARBS, TRICONTOUR, TRICONTOURF, TRIPLOT and TRIPCOLOR
– so a rug under a density curve, two KDEs compared on one
frame, isolines over a filled contour, or a scatter over a
triangulated field all draw. Mark.BAR layers with identical
ordered categories share a categorical frame and occupy adjacent
subbands. One Mark.GROUPED_BAR or Mark.STACKED_BAR layer can
instead own the whole category band. POINT/LINE/AREA layers align
to category centers. These dispatch to _render_bar_combo_layers.
Two or more Mark.ARC plots draw concentric rings,
plots[0] outermost. Each ring keeps its own proportions and palette;
legend entries are prefixed with its one-based ring number. Ring
geometry is assigned by the composition, so every input must use
pie()’s default inner_radius_fraction=0. A single ARC layer
renders exactly as that standalone pie or donut. All export backends
use this same layout.
Every other mark raises with the reason: a categorical, polar,
hierarchical or edge-list mark has no continuous x to share;
Mark.CONTOUR/CONTOURF lay out in unpadded grid-index units rather
than the data’s own coordinates; Mark.SINGLE_AXIS pins its
points at the plot rect’s vertical midpoint, which encodes nothing.
render_facets() has no allow-list at all and takes any mark, so it
is what to reach for when a composition here is refused.
A Plot.secondary_axis() layer scales against its own y-domain on
the right edge – not a Mark.RUG layer, which has no y dimension to
scale. A Mark.POINT/EFFECT_SCATTER layer may use color/
color_categories/size encoding with its own scales and legend
section; sections stack in one column in layer order. There is no
per-series legend for flat-colored layers, and the field marks draw
no color bar here, as they draw none standalone.
Domains combine across every layer: the x-axis spans all of them, and
a layer whose y is measured from a baseline – Mark.AREA’s fill
height, Mark.KDE’s density – forces zero into its axis group’s
domain, the rule one Mark.AREA layer has always applied.
Plot.scale_x_log()/scale_y_log() apply only to Mark.POINT/
LINE/AREA/EFFECT_SCATTER, the same restriction a standalone
render has. A stack of nothing but Mark.RUG layers has no y-axis
at all and draws none, as a standalone rugplot() does.
Shared chrome (background, gridlines, axis colors, margins, font
size, Plot.labels() titles) comes from plots[0]; every other
layer’s Theme governs only its own mark (mark_color,
point_radius, line_width, line_smoothing, scaled by its own
Theme.scale). A secondary-axis layer’s y_title captions the right
axis.
Every Plot must share the same .size(); an empty list raises.
Supersampled by plots[0].settings.theme.raster_supersample like render(),
bumping every layer’s scale together on a copy (plots is a plain
borrow).
Args:
- plots (
List[AnyChart])
Returns:
Canvas
Raises:
fn def render_layers[*Cs: ChartLike](*charts: *Cs.values) -> Canvasrender_layers(plots) for charts named one by one, of any mark types: render_layers(bars, line). Each is erased for the shared list; the layout is the same.
Parameters:
- *Cs (
ChartLike)
Args:
- *charts (
*Cs.values)
Returns:
Canvas
Raises: