Marks & transforms
dysonsphere’s composite marks return native Altair layers, so you compose them with + and keep
Altair’s full API.
Strip plot
Section titled “Strip plot”mark_strip() draws a categorical scatter with a median tick and optional mean error bars. Points
are jittered by default.
import dysonsphere as dsfrom vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon"])origins = ["USA", "Europe", "Japan"]
chart = ds.mark_strip(cars, "Origin", "Miles_per_Gallon", origins, yTitle="Miles per gallon")Set scatter="beeswarm" to pack points with collision avoidance instead of random jitter:
import polars as plimport dysonsphere as dsfrom vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Acceleration"])# Subsample to 50 cars per origin so the swarm fits its band.cars = cars.filter(pl.int_range(pl.len()).shuffle(seed=7).over("Origin") < 50)origins = ["USA", "Europe", "Japan"]
# scatter="beeswarm" packs points analytically instead of random jitter.chart = ds.mark_strip( cars, "Origin", "Acceleration", origins, scatter="beeswarm", yTitle="0-60 mph time (s)",)Overlay mean error bars with errorbars=True; errorbarExtent chooses "sem" (default) or
"sd":
import dysonsphere as dsfrom vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon"])origins = ["USA", "Europe", "Japan"]
# Mean +/- error bars overlaid on the points; errorbarExtent is "sem" (default)# for the standard error of the mean, or "sd" for the standard deviation.chart = ds.mark_strip( cars, "Origin", "Miles_per_Gallon", origins, errorbars=True, errorbarExtent="sd", yTitle="Miles per gallon",)Violin plot
Section titled “Violin plot”mark_violin() pairs a kernel-density silhouette with an embedded boxplot. The silhouette and the
box are styled independently:
import dysonsphere as dsfrom vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Horsepower"])origins = ["USA", "Europe", "Japan"]
chart = ds.mark_violin(cars, "Origin", "Horsepower", origins, yTitle="Horsepower")import dysonsphere as dsfrom vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Horsepower"])origins = ["USA", "Europe", "Japan"]
# Style the silhouette and the embedded boxplot independently.chart = ds.mark_violin( cars, "Origin", "Horsepower", origins, palette=ds.palette("dusk", 3), fillOpacity=0.85, boxplotColor="black", medianColor="white", yTitle="Horsepower",)Boxplot
Section titled “Boxplot”Plain Altair marks inherit the theme too. mark_boxplot() gets grey boxes, a single-stroke median,
and rounded whisker caps out of the box; boxplotOutliers=False hides outlier points.
import altair as altimport dysonsphere as dsfrom vega_datasets import data
# Plain Altair marks inherit the theme too: grey boxes, single-stroke median,# rounded whisker caps. boxplotOutliers=False hides outlier points.ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon"])
chart = ( alt.Chart(cars) .mark_boxplot() .encode( x=alt.X("Origin:N", title=None), y=alt.Y("Miles_per_Gallon:Q", title="Miles per gallon"), ))Transforms
Section titled “Transforms”The jitter and beeswarm offsets are also available as standalone transforms that add a column to
your DataFrame, which you then feed to Altair’s xOffset encoding - handy when you want the offset
on your own custom mark.
import altair as altimport dysonsphere as dsfrom vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon"])
# add_jitter() adds a Gaussian x-offset column; pass it to Altair's xOffset.cars = ds.add_jitter(cars)
chart = ( alt.Chart(cars) .mark_circle() .encode( x=alt.X("Origin:N", title=None), y=alt.Y("Miles_per_Gallon:Q", title="Miles per gallon"), xOffset=alt.XOffset("jitter_x:Q"), ))import altair as altimport dysonsphere as dsfrom vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Miles_per_Gallon"])
# add_beeswarm() computes collision-avoiding x-offsets per group.cars = ds.add_beeswarm(cars, "Miles_per_Gallon", groupBy=["Origin"])
chart = ( alt.Chart(cars) .mark_circle() .encode( x=alt.X("Origin:N", title=None), y=alt.Y("Miles_per_Gallon:Q", title="Miles per gallon"), xOffset=alt.XOffset("beeswarm_x:Q"), ))