Minimal call
import random
rng = random.Random(15)
data = {"row": [], "value": []}
for i, row in enumerate(["a", "b", "c", "d"]):
data["row"] += [row] * 150
data["value"] += [rng.gauss(i, 1.2) for _ in range(150)]
c = pt.chart(data, aes(x="row", y="value"), xlabel="value")
c.add_ridge(overlap=1.5)
c.yticks([])
Worked example
import random
import plotlet as pt
from plotlet import aes
rng = random.Random(15)
months = ["Jan", "Feb", "Mar", "Apr", "May"]
data = {"month": [], "temp": []}
for i, month in enumerate(months):
for _ in range(200):
data["month"].append(month)
data["temp"].append(rng.gauss(20 + i, 3))
c = pt.chart(data, aes(x="month", y="temp"),
title="daily temperature", xlabel="temperature (°C)",
data_width=320, data_height=240)
c.add_ridge(overlap=1.6)
c.yticks([])
Docstring
Ridgeline / joyplot — stacked, vertically-offset KDE curves.
Seaborn's deprecated `kdeplot(..., multiple="stack")` and R's
`ggridges::geom_density_ridges`. Each series gets its own baseline on y;
densities are KDE-shaped via a Gaussian kernel. Handy for showing
distributions across many groups.
The whole stack is rendered as one artist so it owns its own y-baselines.
Categories are placed at integer y; densities are scaled to a fraction of
the row spacing.
API (long-form only):
c.add_ridge(aes(x="label", y="value"))
c.add_ridge(aes(x="label", y="value", color="cohort")) # overlaid
# sub-densities
# per row
Aesthetics:
color= bare → literal fill color; aes(color="col") → one
overlaid KDE per level within each row (ggridges
fill= second factor)
palette= maps levels → colors when color is mapped in aes
Styling kwargs:
overlap=1.4 height of each ridge as a fraction of row spacing
(>1 lets neighbouring ridges overlap)
bw=None bandwidth override; defaults to Silverman's rule
n_grid=200 KDE evaluation grid resolution
alpha=0.6 fill opacity