plotlet v0.6.2

violin

Categorical

["a","b","c"]

Minimal call

import random
rng = random.Random(1)
data = {"grp": [], "value": []}
for i, grp in enumerate(["a", "b", "c"]):
    data["grp"] += [grp] * 80
    data["value"] += [rng.gauss(5 + i, 1) for _ in range(80)]

c = pt.chart(data, aes(x="grp", y="value"), ylabel="value")
c.add_violin()

Worked example

["Adelie","Gentoo","Chinstrap"]
import math

import plotlet as pt
from plotlet import aes

raw = pt.load_dataset("penguins")
keep = [i for i in range(len(raw["species"]))
        if isinstance(raw["sex"][i], str)
        and not math.isnan(raw["body_mass_g"][i])]
df = {k: [raw[k][i] for i in keep] for k in ("species", "sex", "body_mass_g")}

c = pt.chart(df, aes(x="species", y="body_mass_g", fill="sex"),
             title="body mass by species and sex",
             ylabel="body mass (g)",
             data_width=380, data_height=220)
c.add_violin(inner="box")

Docstring

Mirrored KDE outline per category with a mini-boxplot inside.

Long-form only:
  c.add_violin(aes(x="cat", y="value"))
  c.add_violin(aes(x="cat", y="value", fill="group"), palette={...})

Mapping `aes(fill="col")` dodges sub-violins side-by-side within each cat
and emits one legend entry per group level.

Aesthetics:
  fill=True/<literal>/False        body fill (True = palette/cycle default,
                                   bare literal color string, or False for
                                   outline-only); aes(fill="col") → grouping
  color=<literal>      outline / inner-box stroke (defaults to frame color)
  palette=             maps group levels → fills when fill is mapped in aes

Other styling kwargs:
  orientation='v'       'h' for horizontal (cats on y axis)
  width=0.8             total dodge-group width as a band fraction
  gap=0.1               slot-gap fraction between dodged violins
  inner='box'           'box' mini-boxplot (Q1-Q3 + median + whiskers),
                        'quartile' three dashed Q1/Q2/Q3 lines, None KDE only
  trim=True             clip KDE at min/max of data; False extends 10 % past
  fill_alpha=0.4        body-fill opacity
  linewidth=1           outline / inner-box stroke width
  whis=1.5              IQR multiplier for whisker fences (inner='box')
  inner_box_fill=<bg>   mini-boxplot fill; defaults to figure background so
                        the box reads as negative space on any theme
  n_grid=80             KDE evaluation grid resolution
  bw_adjust=1.0         Silverman bandwidth multiplier (>1 smoother)