violin

Configuration Structure

violin: {
bandwidthScale: number,
kde: { ... },
bandwidth: number,
resolution: number,
normalize: 'individual' | 'group',
side: 'both' | 'left' | ...,
box: { ... },
show: boolean,
width: string | number,
whiskers: 'minmax' | 'tukey',
strokeWidth: number,
fillColor: string,
capWidth: number,
points: { ... },
show: boolean,
shape: 'circle' | 'square',
size: number,
jitter: number,
constrainToViolin: boolean,
position: 'center' | 'left' | ...,
laneWidth: string | number,
maxPoints: number,
opacity: number,
fillColor: string,
strokeColor: string,
strokeWidth: number,
colorScale: { ... },
colors: string[],
min: number,
max: number,
steps: number,
}

plotOptions

bandwidthScale

Default: 1

Multiplies the density-derived half-width of each violin. At 1, a curve's own peak density maps to half the category slot. Values above 1 widen the curves, below 1 narrow them.

kde

Kernel density estimation, used only when the density is derived from raw observations: a datum supplying points, or a flat number array as y. A precomputed density profile is drawn exactly as given and ignores this.

Requires the optional stats feature, which the default apexcharts bundle already includes.

bandwidth

violin.kde.bandwidth
Default: undefined

Kernel width in value units. Unset uses Silverman's rule of thumb.

This is the statistical parameter, and it changes the shape of the estimate: too small and the curve turns spiky, too large and real structure is smoothed away. bandwidthScale is unrelated, it only scales the drawn width.

resolution

violin.kde.resolution
Default: 64

Density samples per violin.

normalize

Default: 'individual'

How violin widths are scaled across the series.

Available Options:

  • 'individual' (default): each violin is scaled to its own peak, so every curve fills the slot regardless of sample size.
  • 'group': all violins share one scale (the densest in the series), keeping widths proportional to density across categories.

side

Default: 'both'

Available since v7.1.0. Which side(s) of the category centreline the density is drawn on.

Available Options:

  • 'both' (default): the classic symmetric violin.
  • 'left' / 'right': a half-violin on vertical charts, with the curve on that side and a straight baseline on the other.
  • 'top' / 'bottom': the same, on horizontal charts.

The raincloud chart type presets this to 'right', or 'top' when horizontal. A plain violin can use it too.

plotOptions: {
  violin: {
    side: 'right'
  }
}

box

Available since v7.1.0. A five-number-summary box beside the density, in its own lane out of the category slot.

Drawn only when a datum carries y.summary, either supplied directly as [whiskerLow, q1, median, q3, whiskerHigh] or derived from the raw sample by the raincloud feature.

The rain/jitter layer is the outlier display, so the box draws no outlier dots of its own.

show

violin.box.show
Default: false

Whether to draw the summary box. The raincloud preset turns it on.

Turning it off reflows its lane, so the observations sit directly against the density baseline rather than leaving a dead strip.

width

violin.box.width
Default: '15%'

Fraction of the category slot reserved for the box lane. A percentage string, or a number of pixels.

whiskers

violin.box.whiskers
Default: 'minmax'

How the deriving transform places the whiskers.

Available Options:

  • 'minmax' (default): at the data extremes.
  • 'tukey': at 1.5 x IQR fences, clamped to the data. This is the raincloud preset, and it is safe there because the rain draws every observation, so nothing beyond the whiskers is hidden.

A hand-supplied y.summary is drawn exactly as given and ignores this.

strokeWidth

violin.box.strokeWidth
Default: 1

Stroke width of the box and its whiskers, in px.

fillColor

violin.box.fillColor
Default: undefined

Box fill. Defaults to the series colour.

capWidth

violin.box.capWidth
Default: 0.5

Whisker cap length, as a fraction (0 to 1) of the box lane width.

points

Individual observations ("jitter") overlaid on the violin shape. The raw values come from the points array on each data point's y.

show

violin.points.show
Default: true

Render the jitter dots over each violin.

Available Options:

  • true (default)
  • false

shape

violin.points.shape
Default: 'circle'

Marker shape for each observation.

Available Options:

  • 'circle' (default)
  • 'square'

size

violin.points.size
Default: 2.5

Marker radius in pixels.

jitter

violin.points.jitter
Default: 0.5

Horizontal scatter of the dots as a 0..1 fraction of the violin's half-width. 0 stacks every dot on the centre line.

constrainToViolin

violin.points.constrainToViolin
Default: true

Clamp the jitter to the density width at each value so dots stay inside the curve outline.

Available Options:

  • true (default)
  • false

position

violin.points.position
Default: 'center'

Available since v7.1.0. Where the observations are scattered.

Available Options:

  • 'center' (default): across the slot centreline, under the density. The classic violin jitter.
  • 'left' / 'right' / 'top' / 'bottom': in their own lane on that side, which is the raincloud "rain". The raincloud preset uses 'left', or 'bottom' when horizontal.

Off-centre dots ignore points.constrainToViolin: they no longer sit under the curve, so there is no width to clamp them to.

plotOptions: {
  violin: {
    side: 'right',
    points: {
      position: 'left',
      jitter: 0.85
    }
  }
}

laneWidth

violin.points.laneWidth
Default: '40%'

Available since v7.1.0. Fraction of the category slot given to the off-centre dot lane. A percentage string, or a number of pixels. Ignored when points.position is 'center'.

maxPoints

violin.points.maxPoints
Default: 3000

Cap on the number of dots drawn per violin. Observations beyond this are stride-thinned (evenly sampled) so dense groups stay performant.

opacity

violin.points.opacity
Default: 0.9

Opacity of the dots, from 0 to 1.

fillColor

violin.points.fillColor
Default: 'series-dark'

Fill colour of the dots. Accepts 'series-dark' (a darker shade of the violin's own colour), 'series' (the violin's colour as-is), or any literal colour string such as '#fff'.

strokeColor

violin.points.strokeColor
Default: '#fff'

Colour of the ring around each dot.

strokeWidth

violin.points.strokeWidth
Default: 1

Width of the dot outline in pixels. 0 disables the outline.

colorScale

violin.points.colorScale

Colour each dot by its value along a ramp, overriding fillColor. Dots are bucketed into steps shades to keep rendering fast.

colors

violin.points.colorScale.colors
Default: undefined

Hex colour stops, ordered low → high.

min

violin.points.colorScale.min
Default: undefined

Value mapped to the first colour stop. Defaults to the data minimum.

max

violin.points.colorScale.max
Default: undefined

Value mapped to the last colour stop. Defaults to the data maximum.

steps

violin.points.colorScale.steps
Default: 24

Number of shade buckets between min and max.