Palettes
Every dysonsphere palette is built in Oklab and
resampled by arc length, so sequential ramps step evenly in perceived lightness and diverging ramps
balance around a neutral midpoint. Pass a palette name anywhere a palette= argument is accepted,
or pull colors directly with ds.palette(name, n).
Using a palette
Section titled “Using a palette”ds.palette(name, n) returns n evenly spaced stops; start, end, step, and reverse give
finer control. Feed the result into any Altair scale=alt.Scale(range=...):
import polars as plimport altair as altimport dysonsphere as ds
ds.theme()
# palette() slices/samples any of the 300+ palettes: n evenly spaced stops,# or start/end/step/reverse for full control.df = pl.DataFrame({"dose": ["0", "1", "10", "100"], "response": [8.0, 21.0, 55.0, 89.0]})
chart = ( alt.Chart(df) .mark_bar() .encode( x=alt.X("dose:N", sort=None, title="Dose (nM)"), y=alt.Y("response:Q", title="Response (%)"), color=alt.Color( "dose:N", legend=None, sort=None, scale=alt.Scale(range=ds.palette("ember", 4)), ), ))Qualitative categories
Section titled “Qualitative categories”ds.categorical(members=n) returns the CVD-robust qualitative palette (blue / pink / yellow /
green) sized to your group count. The default (members=1) is a flat, tier-major palette -
adjacent categories differ in hue, for unrelated groups:
import dysonsphere as dsfrom vega_datasets import data
# categorical(members=n) returns the CVD-robust qualitative palette sized to# your group count (blue / pink / yellow / green).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, palette=ds.categorical(3), yTitle="Miles per gallon",)For paired data (a treatment measured pre/post, two timepoints per condition), pass
members=2..10: the palette becomes hue-major, so each consecutive block of members
categories is one hue climbing in lightness. Sort the members adjacent and each group reads as a
family:
import altair as altimport polars as pl
import dysonsphere as ds
ds.theme(chartWidth=170, xLabelAngle=-45)
# Paired data: each treatment measured at two timepoints. categorical(members=2) returns a# hue-major palette - each consecutive pair of categories is one hue climbing in lightness, so# related bars read as a group. (members=1, the default, gives the tier-major flat palette where# adjacent categories differ in hue - for UNRELATED groups.)df = pl.DataFrame( { "condition": ["A pre", "A post", "B pre", "B post", "C pre", "C post", "D pre", "D post"], "response": [4.2, 7.8, 3.9, 6.1, 5.0, 9.2, 4.4, 5.5], })
chart = ( alt.Chart(df) .mark_bar() .encode( x=alt.X("condition:N", sort=None, title=None), y=alt.Y("response:Q", title="Response (AU)"), color=alt.Color( "condition:N", sort=None, scale=alt.Scale(range=ds.categorical(members=2)), legend=None, ), ))Browsing the catalogue
Section titled “Browsing the catalogue”The Palette browser shows all 300+ palettes as filterable swatch strips, with a live preview - click any swatch to copy its hex codes and see the charts restyled with it.
Illustrator swatches
Section titled “Illustrator swatches”ds.export_swatches() writes an Illustrator ExtendScript and an .ase swatch file for the whole
catalogue (or a subset), so the exact colors are available in your vector editor. See the
Palettes reference.