Skip to content
dysonsphere

Nonlinear axes

Vega rounds SVG tick positions to integers, which makes minor ticks on nonlinear axes drift visibly at print DPI. dysonsphere adds correctly spaced minor ticks and fixes the rounding in the exported SVG.

add_log_ticks() adds minor ticks to a log-scale axis (base 10 or any integer base). It wraps your chart and shares its scale.

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme()
stocks = data.stocks()
line = alt.Chart(stocks).mark_line().encode(
x=alt.X("date:T", title=None),
y=alt.Y(
"price:Q",
scale=alt.Scale(type="log"),
# Major ticks on the decades; add_log_ticks() fills in the minors.
axis=alt.Axis(values=[1, 10, 100, 1000]),
title="Price (USD)",
),
color=alt.Color("symbol:N", title="Symbol"),
)
chart = ds.add_log_ticks(line, stocks, "price", axis="y")

log_label_expr() returns a Vega labelExpr for superscript log labels (10¹, 10², …), in "power", "scientific", "e", or "si" notation.

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme()
stocks = data.stocks()
# log_label_expr() returns a Vega labelExpr for typeset log labels (10¹, 10², …).
line = alt.Chart(stocks).mark_line().encode(
x=alt.X("date:T", title=None),
y=alt.Y(
"price:Q",
scale=alt.Scale(type="log"),
axis=alt.Axis(values=[1, 10, 100, 1000], labelExpr=ds.log_label_expr(notation="power")),
title="Price (USD)",
),
color=alt.Color("symbol:N", title="Symbol"),
)
chart = ds.add_log_ticks(line, stocks, "price", axis="y")

add_pow_ticks() does the same for power and square-root scales, interpolating minor ticks evenly in transformed space. Pass the same majorValues you give the main axis.

import altair as alt
import dysonsphere as ds
from vega_datasets import data
ds.theme()
cars = ds.ensure_polars(data.cars()).drop_nulls(["Horsepower", "Weight_in_lbs"])
majors = [0, 1000, 2000, 3000, 4000, 5000]
line = alt.Chart(cars).mark_point().encode(
x=alt.X("Horsepower:Q", title="Horsepower"),
y=alt.Y(
"Weight_in_lbs:Q",
scale=alt.Scale(type="pow", exponent=0.5),
axis=alt.Axis(values=majors),
title="Weight (lbs)",
),
)
# Minor ticks for a power/sqrt axis, evenly spaced in transformed space.
chart = ds.add_pow_ticks(line, cars, "Weight_in_lbs", axis="y", exponent=0.5, majorValues=majors)