Skip to content
dysonsphere

Annotations

Each annotation returns a native Altair layer, so you add it to your chart with +. They share the base chart’s scales, so they land at the right data coordinates automatically.

add_rule() draws horizontal (axis="y", the default) or vertical (axis="x") reference lines at fixed values, with optional labels. strokeDash=None inherits the theme’s dashed-rule style; strokeDash=True/False forces dashed/solid.

import dysonsphere as ds
from vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon"])
origins = ["USA", "Europe", "Japan"]
strip = ds.mark_strip(cars, "Origin", "Miles_per_Gallon", origins, yTitle="Miles per gallon")
# A labeled horizontal reference line; inherits the theme's dashed-rule style.
chart = strip + ds.add_rule(30, label="30 MPG")

axis="x" draws the same line vertically, at a fixed x value:

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon", "Horsepower"])
scatter = alt.Chart(cars).mark_point().encode(
x=alt.X("Horsepower:Q"),
y=alt.Y("Miles_per_Gallon:Q", title="Miles per gallon"),
)
# axis="x" draws vertical rules; pass a list for several at once.
chart = scatter + ds.add_rule(150, axis="x", label="150 hp", strokeDash=True)

Pass a list of values (and a matching list of labels) for several lines in one call. labelPosition chooses which side of the line the label sits on; labelAlign, where along it:

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon", "Horsepower"])
scatter = alt.Chart(cars).mark_point().encode(
x=alt.X("Horsepower:Q"),
y=alt.Y("Miles_per_Gallon:Q", title="Miles per gallon"),
)
# One call places multiple reference lines (a list of values) with per-line labels.
# labelPosition picks which side of the line the label sits on; labelAlign, where along it.
chart = scatter + ds.add_rule(
[20, 30, 40],
label=["economy", "efficient", "hybrid"],
labelAlign="right",
labelPosition="top",
)

add_text() places annotations at data coordinates (numbers share the quantitative scale, strings snap to categories) or at frame positions via nine presets (topLeft, middleCenter, …).

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon", "Horsepower"])
scatter = alt.Chart(cars).mark_point().encode(
x=alt.X("Horsepower:Q"),
y=alt.Y("Miles_per_Gallon:Q", title="Miles per gallon"),
)
# Position presets pin text to the chart frame; data coordinates pin it to values.
chart = (
scatter
+ ds.add_text("n = 392", position="topRight")
+ ds.add_text("outlier cluster", x=200.0, y=32.0, fontSize=5)
)

add_shade() lays a background rectangle layer. In band mode it alternates shades across the x-axis categories; in positions mode it shades explicit coordinate ranges.

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme(palette="blues", xLabelAngle=-45)
barley = data.barley()
sites = ["Morris", "Duluth", "University Farm", "Waseca", "Crookston", "Grand Rapids"]
bar = (
alt.Chart(barley)
.mark_bar()
.encode(
x=alt.X("site:N", sort=sites, title=None),
y=alt.Y("mean(yield):Q", title="Mean yield (bu/acre)"),
color=alt.Color("site:N", legend=None),
)
)
# Band mode: alternate background shades across the x-axis categories.
chart = ds.add_shade(categories=sites, palette=[ds.colors["blues"][0], "white"], opacity=0.5) + bar

In positions mode, a numeric (start, end) tuple shades a fixed range on either axis:

import dysonsphere as ds
from vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon"])
origins = ["USA", "Europe", "Japan"]
strip = ds.mark_strip(cars, "Origin", "Miles_per_Gallon", origins, yTitle="Miles per gallon")
# Positions mode: shade an explicit y-range (e.g. a reference interval).
chart = ds.add_shade(palette=[ds.colors["blues"][0]], positions=[(20.0, 30.0)], axis="y", opacity=0.6) + strip

With axis="both" and a nested ((x0, x1), (y0, y1)) tuple, it shades a 2D region - an intersection rectangle spanning both axes:

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon", "Horsepower"])
scatter = alt.Chart(cars).mark_point().encode(
x=alt.X("Horsepower:Q"),
y=alt.Y("Miles_per_Gallon:Q", title="Miles per gallon"),
)
# axis="both" with a nested ((x_start, x_end), (y_start, y_end)) tuple shades a 2D region -
# an intersection rectangle spanning both axes. Drawn under the points with +.
chart = ds.add_shade(palette=[ds.colors["blues"][0]],
positions=[((40, 100), (28, 48))],
axis="both",
opacity=0.5,
) + scatter

add_labels() auto-places non-overlapping text labels with connector lines for a set of points - volcano gene labels, rank-order labels, cluster labels. Placement is deterministic (no RNG, so figures are reproducible): each label takes the nearest clear spot, and a thin leader line runs from each point to its label. Pass the full plotted df and let labels= select which points to name - an integer picks that many spread evenly across the plot, a list names specific rows.

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme(chartWidth=160, chartHeight=120)
cars = ds.ensure_polars(data.cars()).drop_nulls(["Horsepower", "Miles_per_Gallon"])
scatter = alt.Chart(cars).mark_circle().encode(
x=alt.X("Horsepower:Q"),
y=alt.Y("Miles_per_Gallon:Q", title="Miles per gallon"),
)
# add_labels auto-places non-overlapping labels with connector lines. Deterministic (no RNG),
# so the figure is reproducible. Pass the full df and let labels= select which points to name -
# here, 8 spread evenly across the plot (farthest-point sampling, no cherry-picking).
chart = scatter + ds.add_labels(
cars, "Horsepower", "Miles_per_Gallon", "Name", labels=8
)