Python Charts

Python plotting and visualization demystified

Combine Multiple Altair Charts (Layering & Concatenation)

Combine multiple Altair charts with layering (operator +) and concatenation (| and &).

Altair lets you compose small charts into bigger ones with three operators: + layers charts on shared axes, | places them side by side, and & stacks them vertically. Each is a clean way to build a figure from parts.

Quick Example

Use the operators directly on chart objects.

import altair as alt

layered = chart1 + chart2      # same axes, one plot
row = chart1 | chart2          # horizontal concatenation
column = chart1 & chart2       # vertical concatenation

The + operator is layering, and | / & are concatenation. The same operations exist as alt.layer(), alt.hconcat(), and alt.vconcat().

Layer two charts

+ draws both charts on the same axes. It is the way to overlay a line on top of bars, or to add a threshold to a plot.

bar = alt.Chart(df).mark_bar().encode(
    x=alt.X("month:O", title="Month"),
    y=alt.Y("revenue", title="Revenue (USD)"),
)
target = alt.Chart(df).mark_line(color="#e45756").encode(
    x=alt.X("month:O", title="Month"),
    y=alt.Y("target", title="Revenue (USD)"),
)

(bar + target).properties(title="Layered bar and line")

Altair layered chart with revenue bars and a target line

Because the two layers share the axes, both encodings must use compatible fields. Here the bar shows actual revenue and the line shows the target, so you can see at a glance how far off the bars are.

Layer a line and its points

A line and its points are a natural pair to layer, often to mark individual values on top of the trend.

line = alt.Chart(df).mark_line(color="#f58518").encode(
    x=alt.X("month:O", title="Month"),
    y=alt.Y("conversion", title="Conversion rate", axis=alt.Axis(format=".0%")),
)
points = alt.Chart(df).mark_point(color="#f58518", size=80).encode(
    x=alt.X("month:O", title="Month"),
    y=alt.Y("conversion", title="Conversion rate", axis=alt.Axis(format=".0%")),
)

(line + points).properties(title="Layered line and points")

Altair layered chart of a line and points

Because both layers use the same conversion encoding, the shared axis scales once and the points sit exactly on the line.

Concatenate side by side

| places charts horizontally. It is useful for a small row of related charts that share the same data.

bar = alt.Chart(df).mark_bar().encode(
    x=alt.X("month:O", title=None), y=alt.Y("revenue", title="Revenue"))
line = alt.Chart(df).mark_line(point=True).encode(
    x=alt.X("month:O", title=None), y=alt.Y("revenue", title="Revenue"))

(bar | line).properties(title="Bar and line")

Altair horizontal concatenation of a bar chart and a line chart

Each child keeps its own axes, and the two sit side by side in the output. Give both a matching width and height so the row lines up.

Stack them vertically

Use & to stack charts one above the other. This is a clean way to show two series that do not share a scale, like revenue and conversion rate.

conv = alt.Chart(df).mark_bar(color="#54a24b").encode(
    x=alt.X("month:O", title=None),
    y=alt.Y("conversion", title="Conversion", axis=alt.Axis(format=".0%")),
)

(bar & conv).properties(title="Revenue and conversion")

Altair vertical concatenation of a revenue chart above a conversion chart

Vertical concatenation is the clean answer when two series have very different magnitudes and would squash each other on a shared axis.

Practical Tips

  • Use + (layer) to overlay chart marks that belong on the same axes.
  • Use | and & for side-by-side and stacked views when the scales do not mix.
  • Pass matching width/height to child charts so concatenations align.
  • Use alt.layer(), alt.hconcat(), alt.vconcat() named functions if the operators read oddly for you.
  • Remember layers share axes, while concatenations give each child its own.

Similar Topics