ferrum.composition¶
Compound view classes for combining multiple charts into a single output.
Multi-chart composition primitives (HConcat, VConcat, Joint, Repeat, ClusterMap).
HConcatChart ¶
Bases: _CompositeBase
Horizontal concatenation of two or more charts.
Each sub-chart retains its own scales, axes, and legend. Construct via
the | operator on Chart instances or directly with a list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
charts
|
list of Chart
|
Sub-charts to concatenate left-to-right. |
required |
spacing
|
float
|
Horizontal pixel gap between adjacent charts. |
10.0
|
Examples:
>>> import ferrum as fm
>>> combined = fm.Chart(df).encode(x="hp", y="mpg").mark_point() | fm.Chart(df).encode(x="hp").mark_histogram()
>>> combined.save("side_by_side.svg")
show_svg ¶
Render the horizontally concatenated charts to an SVG string.
Returns:
| Type | Description |
|---|---|
str
|
SVG markup with sub-charts placed left-to-right. |
show_png ¶
Render to PNG bytes (2x retina by default).
Rasterises the SVG produced by show_svg() through the Rust
resvg pipeline -- the same rasteriser Chart.show_png() uses,
with the same 2x default scale.
Returns:
| Type | Description |
|---|---|
bytes
|
PNG image as raw bytes suitable for |
save ¶
Save the composition to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Destination file path. The extension determines the format when format is omitted. |
required |
format
|
str
|
|
None
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If format is not |
share_scale ¶
Share scales across this composition's member charts.
Computes the union domain for each channel marked "shared"
and re-emits every member chart with an explicit scale= dict
on that channel, so the participating axes lock to the same
ticks. Channels marked "independent" (the default for any
channel not listed) keep their per-chart domains.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**channels
|
str
|
Channel name → |
{}
|
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new composition of the same type with the shared scales
injected. No-op (returns |
Raises:
| Type | Description |
|---|---|
ValueError
|
If any value is not |
Examples:
theme ¶
Apply a theme to every sub-chart and return a new composition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
Theme
|
Theme value to apply. |
required |
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new instance of the same composition class with t applied to each sub-chart. |
properties ¶
Forward properties(**kwargs) to every sub-chart.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Keyword arguments accepted by |
{}
|
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new instance of the same composition class with updated sub-chart properties. |
VConcatChart ¶
Bases: _CompositeBase
Vertical concatenation of two or more charts.
Each sub-chart retains its own scales, axes, and legend. Construct via
the & operator on Chart instances or directly with a list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
charts
|
list of Chart
|
Sub-charts to stack top-to-bottom. |
required |
spacing
|
float
|
Vertical pixel gap between adjacent charts. |
10.0
|
Examples:
>>> import ferrum as fm
>>> stacked = fm.Chart(df).encode(x="hp", y="mpg").mark_point() & fm.Chart(df).encode(x="hp").mark_histogram()
>>> stacked.save("stacked.svg")
show_svg ¶
Render the vertically concatenated charts to an SVG string.
Returns:
| Type | Description |
|---|---|
str
|
SVG markup with sub-charts stacked top-to-bottom. |
show_png ¶
Render to PNG bytes (2x retina by default).
Rasterises the SVG produced by show_svg() through the Rust
resvg pipeline -- the same rasteriser Chart.show_png() uses,
with the same 2x default scale.
Returns:
| Type | Description |
|---|---|
bytes
|
PNG image as raw bytes suitable for |
save ¶
Save the composition to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Destination file path. The extension determines the format when format is omitted. |
required |
format
|
str
|
|
None
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If format is not |
share_scale ¶
Share scales across this composition's member charts.
Computes the union domain for each channel marked "shared"
and re-emits every member chart with an explicit scale= dict
on that channel, so the participating axes lock to the same
ticks. Channels marked "independent" (the default for any
channel not listed) keep their per-chart domains.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**channels
|
str
|
Channel name → |
{}
|
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new composition of the same type with the shared scales
injected. No-op (returns |
Raises:
| Type | Description |
|---|---|
ValueError
|
If any value is not |
Examples:
theme ¶
Apply a theme to every sub-chart and return a new composition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
Theme
|
Theme value to apply. |
required |
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new instance of the same composition class with t applied to each sub-chart. |
properties ¶
Forward properties(**kwargs) to every sub-chart.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Keyword arguments accepted by |
{}
|
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new instance of the same composition class with updated sub-chart properties. |
JointChart ¶
Bases: _ChartLike
Joint distribution view: center chart plus optional top and right marginals.
Lays out a 2 × 2 grid: center chart occupies the bottom-left cell, top marginal goes top-left, right marginal goes bottom-right, and the top-right corner is empty. The x-axis is shared between the center and top charts; the y-axis is shared between the center and right charts.
The cell size ratio between the center and each marginal is controlled by
ratio. A ratio of 5 gives the center 5/(5+1) of each dimension and
each marginal 1/(5+1).
Most users obtain a JointChart from ferrum.jointplot rather than
constructing one directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
Chart
|
Primary scatter / distribution chart occupying the main panel. |
required |
top
|
Chart
|
Marginal chart drawn above the center (e.g. a histogram of the x variable). |
None
|
right
|
Chart
|
Marginal chart drawn to the right of the center (e.g. a histogram of the y variable). |
None
|
ratio
|
int
|
Size ratio of the center panel to each marginal panel. Must be > 0. |
5
|
spacing
|
float
|
Pixel gap between adjacent cells. |
10.0
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If ratio is not > 0. |
Examples:
properties ¶
Forward properties(**kwargs) to the center chart.
The marginals (top, right) are kept unchanged because their width /
height is derived from the center plus ratio at render time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Keyword arguments accepted by |
{}
|
Returns:
| Type | Description |
|---|---|
JointChart
|
A new instance with updated center-chart properties. |
show_svg ¶
Render the joint chart to an SVG string.
Returns:
| Type | Description |
|---|---|
str
|
SVG markup with the 2 × 2 grid layout. |
show_png ¶
Render to PNG bytes (2x retina by default).
Rasterises the SVG produced by show_svg() through the Rust
resvg pipeline -- the same rasteriser Chart.show_png() uses,
with the same 2x default scale.
Returns:
| Type | Description |
|---|---|
bytes
|
PNG image as raw bytes suitable for |
save ¶
Save the composition to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Destination file path. The extension determines the format when format is omitted. |
required |
format
|
str
|
|
None
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If format is not |
share_scale ¶
Share scales across this composition's member charts.
Computes the union domain for each channel marked "shared"
and re-emits every member chart with an explicit scale= dict
on that channel, so the participating axes lock to the same
ticks. Channels marked "independent" (the default for any
channel not listed) keep their per-chart domains.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**channels
|
str
|
Channel name → |
{}
|
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new composition of the same type with the shared scales
injected. No-op (returns |
Raises:
| Type | Description |
|---|---|
ValueError
|
If any value is not |
Examples:
RepeatChart ¶
Bases: _ChartLike
Repeat a template chart over a grid of row / column field combinations.
Use Repeat.column, Repeat.row, or Repeat.layer typed sentinels
in the template's .encode(...) call to mark which encoding channel
receives the per-cell field substitution. RepeatChart.expand()
materializes the grid into fully-resolved (row_field, col_field, Chart)
tuples.
diagonal= provides an alternate template for cells where
row_field == col_field (symmetric n × n repeat). corner=True
filters the expanded grid to the lower triangle including the diagonal.
Most users obtain a RepeatChart through Chart.repeat() or
ferrum.pairplot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
template
|
Chart
|
Template chart whose |
required |
row
|
list of str
|
Field names assigned to the row axis. |
None
|
column
|
list of str
|
Field names assigned to the column axis. |
None
|
layer
|
list of str
|
Field names assigned to the layer axis (for non-grid repeat layouts). |
None
|
diagonal
|
Chart
|
Alternate template used when |
None
|
corner
|
bool
|
When |
False
|
spacing
|
float
|
Pixel gap between adjacent cells. |
10.0
|
columns
|
int
|
Maximum number of columns for a wrapped 1-D repeat layout (no-op for 2-D row/column repeat). |
None
|
resolve
|
dict
|
Per-channel scale-sharing overrides — e.g.
|
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If diagonal is set but row or column is not. |
Examples:
>>> import ferrum as fm
>>> base = fm.Chart(df).encode(x=fm.Repeat.column, y=fm.Repeat.row).mark_point()
>>> grid = fm.RepeatChart(base, row=["mpg", "hp"], column=["mpg", "hp"])
>>> grid.save("pair_grid.svg")
expand ¶
Materialize the template into fully-resolved chart cells.
Cell iteration shape:
- 2-D grid (both row and column set):
len(row) × len(column)cells, optionally filtered by corner; diagonal substitutes the template onrow_field == col_fieldcells. - 1-D wrap (only one of row or column set): the populated
field list, paired with
Noneon the missing axis. Geometry is applied by :meth:show_svgdriven bycolumns. - Layer-only (
layer=set, row and column bothNone): a single cell containing all layers.
When layer= is set, each cell becomes a layered Chart
with one layer per element in self.layer (substituted into
every Repeat.layer placeholder). Diagonal cells skip
layering — the diagonal template already defines that cell.
Returns:
| Type | Description |
|---|---|
list of tuple
|
Each element is |
Raises:
| Type | Description |
|---|---|
ValueError
|
If diagonal is set but |
share_scale ¶
Share scales across this repeat's cells by merging into resolve=.
Equivalent to constructing the chart with resolve={...} set
— both paths run through :meth:_apply_resolve at expand()
time, so the union-domain computation sees every cell (including
each layer of layered cells) exactly once. Passing the same
channel twice with different modes takes the call's value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**channels
|
str
|
Channel name → |
{}
|
Returns:
| Type | Description |
|---|---|
RepeatChart
|
A new |
show_svg ¶
Render the repeated grid to an SVG string.
Returns:
| Type | Description |
|---|---|
str
|
SVG markup containing all materialized cell charts in a grid. |
Notes
2-D grids (both row and column set) lay out as
len(row) × len(column). 1-D layouts (only one axis set) wrap
by columns — column-only spreads left-to-right and wraps
downward; row-only spreads top-to-bottom in a single column unless
columns opens additional columns. When columns is unset
the 1-D layout is a single row (column-only) or column (row-only).
show_png ¶
Render to PNG bytes (2x retina by default).
Rasterises the SVG produced by show_svg() through the Rust
resvg pipeline -- the same rasteriser Chart.show_png() uses,
with the same 2x default scale.
Returns:
| Type | Description |
|---|---|
bytes
|
PNG image as raw bytes suitable for |
save ¶
Save the composition to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Destination file path. The extension determines the format when format is omitted. |
required |
format
|
str
|
|
None
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If format is not |
theme ¶
Apply a theme to every sub-chart and return a new composition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
Theme
|
Theme value to apply. |
required |
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new instance of the same composition class with t applied to each sub-chart. |
properties ¶
Forward properties(**kwargs) to every sub-chart.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Keyword arguments accepted by |
{}
|
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new instance of the same composition class with updated sub-chart properties. |
ClusterMapChart ¶
Bases: _ChartLike
Clustered heatmap with optional row and column dendrograms.
Lays out a 2 × 2 grid: the heatmap occupies the bottom-right cell, the column dendrogram goes top-right, the row dendrogram (rotated 90°) goes bottom-left, and the top-left corner is empty. Dendrogram value axes are hidden; categorical axes align with the heatmap row/column labels.
Cell size is split by dendrogram_ratio: dendrograms receive that
fraction of the total width/height, the heatmap receives the remainder.
Most users obtain a ClusterMapChart from ferrum.clustermap rather
than constructing one directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
heatmap
|
Chart
|
The central heatmap chart. |
required |
row_dendrogram
|
Chart
|
Dendrogram chart for the row axis. Displayed to the left of the heatmap, rotated 90°. |
None
|
col_dendrogram
|
Chart
|
Dendrogram chart for the column axis. Displayed above the heatmap. |
None
|
dendrogram_ratio
|
float
|
Fraction of the total width/height allocated to each dendrogram panel. Must be in the open interval (0, 1). |
0.2
|
spacing
|
float
|
Pixel gap between adjacent cells. |
10.0
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If dendrogram_ratio is not in the open interval (0, 1). |
Examples:
>>> import ferrum as fm
>>> cm = fm.clustermap(df, method="ward", cmap="rdbu")
>>> cm.save("clustermap.svg")
charts
property
¶
List of Chart : All non-None sub-charts in __init__ order
(heatmap, row_dendrogram, col_dendrogram).
properties ¶
Forward properties(**kwargs) to the heatmap chart.
The dendrogram panels are kept unchanged because their width / height
is derived from the heatmap plus dendrogram_ratio at render time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Keyword arguments accepted by |
{}
|
Returns:
| Type | Description |
|---|---|
ClusterMapChart
|
A new instance with updated heatmap-chart properties. |
show_svg ¶
Render the cluster map to an SVG string.
Returns:
| Type | Description |
|---|---|
str
|
SVG markup with the 2 × 2 grid layout. |
show_png ¶
Render to PNG bytes (2x retina by default).
Rasterises the SVG produced by show_svg() through the Rust
resvg pipeline -- the same rasteriser Chart.show_png() uses,
with the same 2x default scale.
Returns:
| Type | Description |
|---|---|
bytes
|
PNG image as raw bytes suitable for |
save ¶
Save the composition to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Destination file path. The extension determines the format when format is omitted. |
required |
format
|
str
|
|
None
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If format is not |
share_scale ¶
Share scales across this composition's member charts.
Computes the union domain for each channel marked "shared"
and re-emits every member chart with an explicit scale= dict
on that channel, so the participating axes lock to the same
ticks. Channels marked "independent" (the default for any
channel not listed) keep their per-chart domains.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**channels
|
str
|
Channel name → |
{}
|
Returns:
| Type | Description |
|---|---|
_ChartLike
|
A new composition of the same type with the shared scales
injected. No-op (returns |
Raises:
| Type | Description |
|---|---|
ValueError
|
If any value is not |
Examples: