How to make `seaborn.violinplot` fit between extrema, but not cut?
Oct 7, 10:47pm
Short answer
Seaborn's violin is a Gaussian KDE, so its density is non‑zero at your data's min/max. That gives you exactly two native behaviors:
cut=0 → the violin stops exactly at the extrema, but the end is a flat truncation (it looks "cut").
Default (cut=2) → smooth tails, but they spill past the extrema.
There's no parameter that gives "bounded by extrema and smoothly tapering to zero" at the same time, because a Gaussian KDE simply doesn't vanish at the sample extremes. So you have three practical options:
Option 3 — draw the violin yourself with tapered ends
Compute the KDE, then ramp the density down to zero over ~one bandwidth at each end. This spans exactly [min, max] with no flat cut:
python
import numpy as np
from scipy.stats import gaussian_kde
def violin(ax, data, pos=0, width=0.8, n=200):
data = np.asarray(data, float)
lo, hi = data.min(), data.max()
kde = gaussian_kde(data)
grid = np.linspace(lo, hi, n)
dens = kde(grid)
# effective bandwidth, used as the taper length
h = kde.factor * data.std(ddof=1)
# smooth cosine ramp: 0 at the extrema, 1 one bandwidth inside
ramp = 0.5 * (1 - np.cos(np.pi * np.clip((grid - lo) / h, 0, 1)))
ramp *= 0.5 * (1 - np.cos(np.pi * np.clip((hi - grid) / h, 0, 1)))
dens = dens * ramp
dens = dens / dens.max() * (width / 2)
ax.fill_betweenx(grid, pos - dens, pos + dens, alpha=0.7)
# usage, e.g. with the tips dataset:
# fig, ax = plt.subplots()
# for i, (day, g) in enumerate(df.groupby("day")):
# violin(ax, g["total_bill"], pos=i)
# ax.set_xticks(range(df["day"].nunique()), df["day"].unique())
Caveat: Option 3 is a cosmetic taper, not a statistically meaningful boundary correction — the true density at the extrema is unknowable from the sample, so any "smooth fit" is a rendering choice. If you just want the violin to not extend beyond the data, cut=0 is the honest, one‑line answer.
Oct 7, 10:47pm
This is a shared conversation and may include unverified content that doesn't reflect Mistral AI's views. Login to resume chatting.