Minimal call
import random
rng = random.Random(12)
xs = [rng.gauss(0, 1) for _ in range(300)]
df = {"x": xs, "y": [x * 0.5 + rng.gauss(0, 0.8) for x in xs]}
c = pt.chart(df, aes(x="x", y="y"), xlabel="x", ylabel="y")
c.add_kde_2d(n_grid=40, cmap="viridis")
Worked example
import random
import plotlet as pt
from plotlet import aes
rng = random.Random(12)
n = 200
xs = ([rng.gauss(-1, 0.7) for _ in range(n)]
+ [rng.gauss(1.2, 1.0) for _ in range(n)])
ys = ([rng.gauss(0, 1.0) for _ in range(n)]
+ [rng.gauss(2, 0.8) for _ in range(n)])
df = {"x": xs, "y": ys}
c = pt.chart(df, aes(x="x", y="y"),
title="2-D KDE", xlabel="x", ylabel="y",
data_width=300, data_height=260)
c.add_scatter(size=1.2, alpha=0.25, color="#444444")
c.add_kde_2d(n_grid=40, cmap="viridis")
Docstring
2-D Gaussian KDE iso-density contours from a scatter sample.
Estimates a smooth 2-D density from (xs, ys) using a separable Gaussian kernel
on a regular grid, then draws iso-density contours via marching squares. The
visual cousin of hexbin for smaller, smoother samples.
Differs from the cookbook contour recipe, which expects a pre-computed 2-D
scalar grid. Here the grid is estimated from data.
API: c.add_kde_2d(aes(x='col', y='col'))
Aesthetics:
color= bare → literal contour color; aes(color="col") → one
density per level, single-colored (seaborn kdeplot hue)
palette= maps levels → colors when color is mapped in aes
Styling kwargs:
n_grid=60 KDE evaluation grid resolution (n × n)
bw=None bandwidth override; defaults to Silverman's rule per axis
levels=None list of iso-density levels; defaults to 5 quantile levels
fill=False True fills the level regions (seaborn kdeplot fill=True)
instead of stroking iso-lines
cmap=None colormap name for coloring contours by level
(mutually exclusive with aes-mapped color)
alpha=None fill opacity (fill=True only); defaults to 1 with cmap,
0.25 for a single-color fill so levels stack visibly
linewidth=1.2 contour stroke width