%% tikzviolinplots.sty
%% Copyright 2026 Pedro Callil-Soares
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Pedro Callil-Soares.
%
% This work consists of the files tikzviolinplots.sty and
% tikzviolinplots.tex.

\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{tikzviolinplots}[2026/03/31 v0.11.1 Violin plot creation in pgfplots]

\RequirePackage{pgfplots}
\RequirePackage{pgfplotstable}
\RequirePackage{pgfkeys}


\DeclareOption*{\PackageWarning{tikzviolinplots}{Unknown option: ‘\CurrentOption’}}
\ProcessOptions\relax

\newif\ifviolin@scaled
\newif\ifviolin@datapoints
\newif\ifviolin@averages
\newif\ifviolin@nomirror
\newif\ifviolin@reverseaxis
\newif\ifviolin@invert

\pgfkeys{
	/violinplot/.is family,
	/violinplot/.search also=/pgfplots,
	/violinplot,
	%
	scaled/.is if=violin@scaled,
	data points/.is if=violin@datapoints,
	averages/.is if=violin@averages,
	no mirror/.is if=violin@nomirror,
	reverse axis/.is if=violin@reverseaxis,
	invert/.is if=violin@invert,
	%
	xmin/.value required,
	xmax/.value required,
	ymin/.value required,
	ymax/.value required,
	col sep/.value required,
	kernel/.value required,
	bandwidth/.value required,
	index/.value required,
	indexes/.value required,
	frequencies/.value required,
	samples/.value required,
	relative position/.value required,
	spacing/.value required,
	color/.value required,
	primary color/.value required,
	secondary color/.value required,
	fill opacity/.value required,
	label/.value required,
	labels/.value required,
	data label style/.value required,
	average mark/.value required,
	average size/.value required,
	average color/.value required,
	average opacity/.value required,
	average fill/.value required,
	average fill opacity/.value required,
	dataset mark/.value required,
	dataset size/.value required,
	dataset color/.value required,
	dataset opacity/.value required,
	dataset fill/.value required,
	dataset fill opacity/.value required,
	dataset jitter/.value required,
	%
	col sep/.is choice,
	col sep/space/.code=\def\violin@colsep{space},
	col sep/tab/.code=\def\violin@colsep{tab},
	col sep/comma/.code=\def\violin@colsep{comma},
	col sep/colon/.code=\def\violin@colsep{colon},
	col sep/semicolon/.code=\def\violin@colsep{semicolon},
	col sep/braces/.code=\def\violin@colsep{braces},
	col sep/ampersand/.code=\def\violin@colsep{ampersand},
	%
	kernel/.is choice,
	kernel/gaussian/.code=\def\violin@kernel{gaussian},
	kernel/logistic/.code=\def\violin@kernel{logistic},
	kernel/parabolic/.code=\def\violin@kernel{parabolic},
	kernel/uniform/.code=\def\violin@kernel{uniform},
	kernel/triangular/.code=\def\violin@kernel{triangular},
	%
	xmin/.store in = \violin@xmin,
	xmax/.store in = \violin@xmax,
	ymin/.store in = \violin@ymin,
	ymax/.store in = \violin@ymax,
	bandwidth/.store in = \violin@bandwidth,
	index/.store in = \violin@index,
	indexes/.store in = \violin@indexes,
	frequencies/.store in = \violin@frequencies,
	samples/.store in = \violin@samples,
	relative position/.store in = \violin@delta,
	spacing/.store in = \violin@spacing,
	color/.store in = \violin@color,
	primary color/.store in = \violin@color@primary,
	secondary color/.store in = \violin@color@secondary,
	fill opacity/.store in = \violin@fillopacity,
	label/.store in = \violin@label,
	labels/.store in = \violin@labels,
	data label style/.store in = \violin@datalabelstyle,
	average mark/.store in = \violin@avg@mark,
	average size/.store in = \violin@avg@size,
	average color/.store in = \violin@avg@color,
	average opacity/.store in = \violin@avg@opacity,
	average fill/.store in = \violin@avg@fillcolor,
	average fill opacity/.store in = \violin@avg@fillopacity,
	dataset mark/.store in = \violin@pts@mark,
	dataset size/.store in = \violin@pts@size,
	dataset color/.store in = \violin@pts@color,
	dataset opacity/.store in = \violin@pts@opacity,
	dataset fill/.store in = \violin@pts@fillcolor,
	dataset fill opacity/.store in = \violin@pts@fillopacity,
	dataset jitter/.store in = \violin@pts@jitter,
	%
	xmin=-10,
	xmax=10,
	ymin=-10,
	ymax=10,
	%
	xmin/.forward to = {/pgfplots/xmin},
	xmax/.forward to = {/pgfplots/xmax},
	ymin/.forward to = {/pgfplots/ymin},
	ymax/.forward to = {/pgfplots/ymax},
	%
	default/.style = {
		col sep=comma,
		kernel=gaussian,
		bandwidth=NONE,
		index=DATA,
		indexes={A,B,C},
		frequencies=FREQINTERNALVIOLIN,
		samples=50,
		relative position=0,
		spacing=1.0,
		color=black,
		primary color=blue,
		secondary color=black,
		fill opacity=0.5,
		label={LABEL},
		labels={A,B,C},
		data label style={},
		invert=false,
		average mark=x,
		average size=3pt,
		average color=black,
		average opacity=1.0,
		average fill=white,
		average fill opacity=0.5,
		dataset mark=*,
		dataset size=1pt,
		dataset color=black,
		dataset opacity=1.0,
		dataset fill=black,
		dataset fill opacity=0.2,
		dataset jitter=0.0,
	},
	default,
}

\newcommand{\violinsetoptions}[2][]{%
	\pgfkeys@spdef\violin@violinargs{#1}
	\pgfkeys@spdef\violin@pgfplotsargs{#2}
	\edef\violin@args{
		/handler config=only existing,
		/violinplot,
		\expandonce{\violin@violinargs},
		\expandonce{\violin@pgfplotsargs},
		/handler config=all,
	}
	\pgfkeysalsofrom{\violin@args}

	\pgfmathqparse{0}
	\let\violin@numofplots\pgfmathresult  % Needed to distinguish first plot from others in \violinplot
}

\newcommand{\addviolinplot}[2][]{%
	\pgfkeys{/violinplot, #1}

	\edef\violin@filename{#2}

	\pgfkeys{/pgf/fpu}

	\pgfplotstableread[%
		col sep=\violin@colsep,
		trim cells=true,
	]{\violin@filename}\theviolin@dataset@table

	\pgfplotstablegetrowsof{\theviolin@dataset@table}
	\pgfmathparse{int(\pgfmathresult-1)}
	\let\violin@filename@lastindex\pgfmathresult

	\pgfmathqparse{0}
	\let\violin@dataset@stddev\pgfmathresult
	\let\violin@dataset@average\pgfmathresult
	\let\violin@dataset@weightsum\pgfmathresult
	\let\violin@weight@row\pgfmathresult

	% Calculating averages
	\def\violin@frequencies@default{FREQINTERNALVIOLIN}
	\pgfplotstableforeachcolumnelement{\violin@index}\of\theviolin@dataset@table\as\xi{%
		\ifx\violin@frequencies\violin@frequencies@default
			\pgfmathqparse{1}
			\let\violin@dataset@weight\pgfmathresult
		\else
			\pgfplotstablegetelem{\violin@weight@row}{\violin@frequencies}\of{\theviolin@dataset@table}
			\let\violin@dataset@weight\pgfplotsretval
			\pgfmathparse{\violin@weight@row+1}
			\let\violin@weight@row\pgfmathresult
		\fi
		\pgfmathparse{\violin@dataset@weightsum+\violin@dataset@weight}
		\let\violin@dataset@weightsum\pgfmathresult
		\pgfmathparse{\violin@dataset@average+\xi*\violin@dataset@weight}
		\let\violin@dataset@average\pgfmathresult
	}
	\pgfmathparse{\violin@dataset@average/\violin@dataset@weightsum}
	\let\violin@dataset@average\pgfmathresult

	\ifviolin@datapoints
		\pgfplotstablecreatecol[
			create col/assign/.code={
				\let\entry\violin@delta
				\pgfkeyslet{/pgfplots/table/create col/next content}\entry
			}
		]{deltacol}\theviolin@dataset@table
	\fi

	\ifviolin@reverseaxis
		\def\violin@axis@x{y}
		\def\violin@axis@y{x}
	\else
		\def\violin@axis@x{x}
		\def\violin@axis@y{y}
	\fi

	% Bandwidth calculation
	\def\violin@bandwidth@default{NONE}
	\ifx\violin@bandwidth\violin@bandwidth@default
		\pgfmathqparse{0}
		\let\violin@weight@row\pgfmathresult
		% Standard deviation calculation
		\pgfplotstableforeachcolumnelement{\violin@index}\of\theviolin@dataset@table\as\xi{%
			\ifx\violin@frequencies\violin@frequencies@default
				\pgfmathqparse{1}
				\let\violin@dataset@weight\pgfmathresult
			\else
				\pgfplotstablegetelem{\violin@weight@row}{\violin@frequencies}\of{\theviolin@dataset@table}
				\let\violin@dataset@weight\pgfplotsretval
				\pgfmathparse{\violin@weight@row+1}
				\let\violin@weight@row\pgfmathresult
			\fi
			\pgfmathparse{\violin@dataset@stddev+\violin@dataset@weight*(\xi-\violin@dataset@average)^2}
			\let\violin@dataset@stddev\pgfmathresult
		}
		\pgfmathparse{sqrt(\violin@dataset@stddev/\violin@dataset@weightsum)}
		\let\violin@dataset@stddev\pgfmathresult
		\pgfmathparse{1.06*\violin@dataset@stddev*(\violin@dataset@weightsum^(-0.2))}%
		\let\violin@bandwidthcalc\pgfmathresult
	\else
		\let\violin@bandwidthcalc\violin@bandwidth
	\fi

	% Setting limits for curve
	\pgfplotstablegetelem{0}{\violin@index}\of{\theviolin@dataset@table}
	\let\violin@dataset@min\pgfplotsretval
	\let\violin@dataset@max\pgfplotsretval
	\pgfplotstableforeachcolumnelement{\violin@index}\of\theviolin@dataset@table\as\xi{%
		\pgfmathparse{\xi > \violin@dataset@min}
		\pgfmathfloattoint{\pgfmathresult}
		\ifnum\pgfmathresult=0
			\let\violin@dataset@min\xi
		\fi
	}
	\pgfmathparse{\violin@dataset@min - 3*\violin@bandwidthcalc}
	\let\violin@dataset@min\pgfmathresult

	\pgfplotstableforeachcolumnelement{\violin@index}\of\theviolin@dataset@table\as\xi{%
		\pgfmathparse{\xi < \violin@dataset@max}
		\pgfmathfloattoint{\pgfmathresult}
		\ifnum\pgfmathresult=0
			\let\violin@dataset@max\xi
		\fi
	}
	\pgfmathparse{\violin@dataset@max + 3*\violin@bandwidthcalc}
	\let\violin@dataset@max\pgfmathresult

	% Creating curve domain
	\pgfplotstableset{
		create on use/list/.style={create col/expr={
			\violin@dataset@min + (\violin@dataset@max-\violin@dataset@min)
			*(\pgfplotstablerow/(\violin@samples-1))
		}}
	}


	% Calculating KDE
	\pgfplotstablenew[columns={list}]{\violin@samples}\violin@kde

	\pgfmathqparse{0}
	\let\violin@kde@max\pgfmathresult

	\def\violin@kernel@gaussian{gaussian}
	\def\violin@kernel@logistic{logistic}
	\def\violin@kernel@parabolic{parabolic}
	\def\violin@kernel@uniform{uniform}
	\def\violin@kernel@triangular{triangular}

	\pgfplotstablecreatecol[
		create col/assign/.code={
			\pgfmathparse{%
				1.0/(\violin@dataset@weightsum*\violin@bandwidthcalc)
			}
			\let\violin@kde@factor\pgfmathresult
			\pgfmathqparse{0}
			\let\violin@kde@accum\pgfmathresult
			\let\violin@weight@row\pgfmathresult
			\pgfplotstableforeachcolumnelement{\violin@index}\of\theviolin@dataset@table\as\xi{%
				\ifx\violin@frequencies\violin@frequencies@default
					\pgfmathqparse{1}
					\let\violin@dataset@weight\pgfmathresult
				\else
					\pgfplotstablegetelem{\violin@weight@row}{\violin@frequencies}\of{\theviolin@dataset@table}
					\let\violin@dataset@weight\pgfplotsretval
					\pgfmathparse{\violin@weight@row+1}
					\let\violin@weight@row\pgfmathresult
				\fi
				\pgfmathparse{%
					((\xi-\thisrow{list})/%
					\violin@bandwidthcalc)}
				\let\violin@u\pgfmathresult
				%
				\ifx\violin@kernel\violin@kernel@gaussian
					\pgfmathparse{\violin@kde@accum + %
						\violin@dataset@weight*e^(-0.5*\violin@u*\violin@u)/sqrt(2*pi)}
					\let\violin@kde@accum\pgfmathresult
				\fi
				\ifx\violin@kernel\violin@kernel@logistic
					\pgfmathparse{\violin@kde@accum + %
						\violin@dataset@weight*1/(e^\violin@u + 2 + e^(-\violin@u))
					}
					\let\violin@kde@accum\pgfmathresult
				\fi
				\ifx\violin@kernel\violin@kernel@parabolic
					\pgfmathparse{abs(\violin@u) < 1}
					\pgfmathfloattoint{\pgfmathresult}
					\ifnum\pgfmathresult=1
						\pgfmathparse{\violin@kde@accum + %
							\violin@dataset@weight*0.75*(1-\violin@u*\violin@u)
						}
					\else
						\pgfmathparse{\violin@kde@accum}
					\fi
					\let\violin@kde@accum\pgfmathresult
				\fi
				\ifx\violin@kernel\violin@kernel@uniform
					\pgfmathparse{abs(\violin@u) < 1}
					\pgfmathfloattoint{\pgfmathresult}
					\ifnum\pgfmathresult=1
						\pgfmathparse{\violin@kde@accum + \violin@dataset@weight*0.5}
					\else
						\pgfmathparse{\violin@kde@accum}
					\fi
					\let\violin@kde@accum\pgfmathresult
				\fi
				\ifx\violin@kernel\violin@kernel@triangular
					\pgfmathparse{abs(\violin@u) < 1}
					\pgfmathfloattoint{\pgfmathresult}
					\ifnum\pgfmathresult=1
						\pgfmathparse{\violin@kde@accum + %
							\violin@dataset@weight*(1-abs(\violin@u))}
					\else
						\pgfmathparse{\violin@kde@accum}
					\fi
					\let\violin@kde@accum\pgfmathresult
				\fi
			}
			\pgfmathparse{\violin@kde@accum*\violin@kde@factor}
			\let\entry\pgfmathresult
			\pgfkeyslet{/pgfplots/table/create col/next content}\entry
		}
	]{kdecol}\violin@kde

	\pgfplotstableforeachcolumnelement{kdecol}\of\violin@kde\as\entry{%
		\pgfmathparse{\entry < \violin@kde@max}
		\pgfmathfloattoint{\pgfmathresult}
		\ifnum\pgfmathresult=0
			\let\violin@kde@max\entry
		\fi
	}

	\pgfplotstablemodifyeachcolumnelement{kdecol}\of\violin@kde\as\cell{%
		\let\pgfplotstablezero\violin@delta
		\ifnum\pgfplotstablerow=0
			\let\cell\pgfplotstablezero
		\else
			\pgfmathparse{int(\violin@samples-1)}
			\pgfmathfloattoint{\pgfmathresult}
			\ifnum\pgfplotstablerow=\pgfmathresult
				\let\cell\pgfplotstablezero
			\else
				\ifviolin@nomirror
					\pgfmathqparse{1.9}
				\else
					\pgfmathqparse{1}
				\fi
				\let\violin@mirror@factor\pgfmathresult
				\ifviolin@scaled
					\pgfmathparse{\violin@delta+\violin@mirror@factor*0.5*\cell/\violin@kde@max}
				\else
					\pgfmathparse{\violin@delta+\violin@mirror@factor*\cell}
				\fi
				\let\cell\pgfmathresult
			\fi
		\fi
	}

	\ifviolin@nomirror
		\ifviolin@invert
			\pgfplotstablemodifyeachcolumnelement{kdecol}\of\violin@kde\as\cell{%
				\pgfmathparse{-\cell+2*\violin@delta}
				\let\cell\pgfmathresult
			}
		\fi
	\else
		\pgfplotstablecreatecol[
			create col/assign/.code={
				\pgfmathparse{-\thisrow{kdecol}+2*\violin@delta}
				\let\entry\pgfmathresult
				\pgfkeyslet{/pgfplots/table/create col/next content}\entry
			}
		]{kdecolmirror}\violin@kde

		\pgfplotstablenew[columns={list}]{\violin@samples}\violin@kdewithmirror
		\pgfplotstablecreatecol[
			copy column from table={\violin@kde}{kdecol}
		]{kdecol}{\violin@kdewithmirror}
		\pgfplotstablesort[
			sort key=list,
			sort cmp=float <,
		]{\violin@kdewithmirror}{\violin@kdewithmirror}

		\pgfplotstablenew[columns={list}]{\violin@samples}\violin@kdemirror
		\pgfplotstablecreatecol[
			copy column from table={\violin@kde}{kdecolmirror}
		]{kdecol}{\violin@kdemirror}
		\pgfplotstablesort[
			sort key=list,
			sort cmp=float >,
		]{\violin@kdemirror}{\violin@kdemirror}

		\pgfplotstablevertcat{\violin@kdewithmirror}{\violin@kdemirror}
	\fi

	\pgfkeys{/pgf/fpu=false}

	% Data points must be centered only if plot is mirrored
	\ifviolin@nomirror
		\ifviolin@invert
			\def\randfct{(-rnd)}
		\else
			\def\randfct{(rnd)}
		\fi
	\else
		\def\randfct{(rand)}
	\fi

	\ifviolin@nomirror
		\ifviolin@reverseaxis
			\edef\violin@addplot{
				\noexpand\addplot[
					no marks,
					fill=\violin@color,
					fill opacity=\violin@fillopacity,
				] table [
					\violin@axis@x=kdecol, \violin@axis@y=list
				] {\noexpand\violin@kde};
			}
			\violin@addplot
			\edef\violin@addplot{
				\noexpand\addplot[
					no marks,
					color=black,
				] coordinates {
					(\violin@xmin,\violin@delta)%
					(\violin@xmax,\violin@delta)
				};
			}
			\violin@addplot
		\else
			\edef\violin@addplot{
				\noexpand\addplot[
					no marks,
					fill=\violin@color,
					fill opacity=\violin@fillopacity,
				] table [
					\violin@axis@x=kdecol, \violin@axis@y=list
				] {\noexpand\violin@kde};
			}
			\violin@addplot
			\edef\violin@addplot{
				\noexpand\addplot[
					no marks,
					color=black,
				] coordinates {
					(\violin@delta,\violin@ymin)%
					(\violin@delta,\violin@ymax)
				};
			}
			\violin@addplot
		\fi
	\else
		\edef\violin@addplot{
			\noexpand\addplot[
				no marks,
				fill=\violin@color,
				fill opacity=\violin@fillopacity,
			] table [
				\violin@axis@x=kdecol, \violin@axis@y=list
			] {\noexpand\violin@kdewithmirror};
		}
		\violin@addplot
	\fi

	\ifviolin@averages
		\ifviolin@reverseaxis
			\edef\violin@addplot{
				\noexpand\addplot[
					only marks,
					mark=\violin@avg@mark,
					mark size=\violin@avg@size,
					color=\violin@avg@color,
					opacity=\violin@avg@opacity,
					fill=\violin@avg@fillcolor,
					fill opacity=\violin@avg@fillopacity,
				] coordinates {
					(\violin@dataset@average,\violin@delta)
				};
			}
			\violin@addplot
		\else
			\edef\violin@addplot{
				\noexpand\addplot[
					only marks,
					mark=\violin@avg@mark,
					mark size=\violin@avg@size,
					color=\violin@avg@color,
					opacity=\violin@avg@opacity,
					fill=\violin@avg@fillcolor,
					fill opacity=\violin@avg@fillopacity,
				] coordinates {
					(\violin@delta,\violin@dataset@average)
				};
			}
			\violin@addplot
		\fi
	\fi

	\ifviolin@datapoints
		\edef\violin@addplot{
			\noexpand\addplot[
				only marks,
				mark=\violin@pts@mark,
				mark size=\violin@pts@size,
				color=\violin@pts@color,
				opacity=\violin@pts@opacity,
				fill=\violin@pts@fillcolor,
				fill opacity=\violin@pts@fillopacity,
				\violin@axis@x\space
				filter/.expression={\violin@axis@x + \violin@pts@jitter * \randfct}
			] table [
				\violin@axis@x=deltacol,
				\violin@axis@y=\violin@index,
			] {\noexpand\theviolin@dataset@table};
		}
		\violin@addplot
	\fi
}

\newcommand{\violin@getnth}[2]{%
	\pgfmathqparse{0}
	\let\violin@getnth@counter\pgfmathresult
	\let\violin@nthelem\pgfmathresult
	\@for\violin@listelem:=#1\do{
		\ifnum#2=\violin@getnth@counter
			\let\violin@nthelem\violin@listelem
			\pgfmathparse{int(\violin@getnth@counter+1)}
			\let\violin@getnth@counter\pgfmathresult
		\else
			\pgfmathparse{int(\violin@getnth@counter+1)}
			\let\violin@getnth@counter\pgfmathresult
		\fi
	}
}

\newcommand{\violinplot}[2][]{%
	\pgfkeys{/violinplot, default}
	\pgfkeysalsofrom{\violin@args}
	\pgfkeys{/violinplot, #1}

	\def\violin@filename{#2}

	\ifviolin@reverseaxis
		\pgfplotsset{
			yticklabels/.expand once={\violin@label},
			ytick/.expand once={\violin@delta},
			yticklabel style={\violin@datalabelstyle},
		}
	\else
		\pgfplotsset{
			xticklabels/.expand once={\violin@label},
			xtick/.expand once={\violin@delta},
			xticklabel style={\violin@datalabelstyle},
		}
	\fi

	\pgfmathparse{\violin@numofplots!=0}  % Current plot is not first plot
	\ifnum\pgfmathresult=1
		\ifviolin@reverseaxis
			\pgfplotsset{hide x axis}
		\else
			\pgfplotsset{hide y axis}
		\fi

		\pgfplotsset{
			title={},
			xlabel={},
			ylabel={},
			axis line style={draw=none},
			grid={none},
		}
	\fi

	\begin{axis}[
		axis on top,
	]
		\addviolinplot{\violin@filename}
	\end{axis}

	\pgfmathparse{int(\violin@numofplots+1)}
	\let\violin@numofplots\pgfmathresult
}

\newcommand{\violinplotwholefile}[2][]{%
	\pgfkeys{/violinplot, default}
	\pgfkeysalsofrom{\violin@args}
	\pgfkeys{/violinplot, #1}

	\def\violin@filename{#2}

	\pgfmathqparse{0}
	\let\violin@numofplots\pgfmathresult
	\@for\violin@plotindex:=\violin@indexes\do{
		\pgfmathparse{int(\violin@numofplots+1)}
		\let\violin@numofplots\pgfmathresult
	}

	\pgfmathqparse{0}
	\let\violin@counter\pgfmathresult
	\let\violin@relativepos\pgfmathresult

	\pgfmathqparse{1}
	\let\violin@start\pgfmathresult
	\pgfmathparse{1+\violin@spacing}
	\let\violin@step\pgfmathresult
	\pgfmathparse{\violin@spacing*(\violin@numofplots-\violin@start)+\violin@start}
	\let\violin@stop\pgfmathresult

	\ifviolin@reverseaxis
		\pgfplotsset{
			yticklabels/.expand once={\violin@labels},
			ytick/.expand once={\violin@start, \violin@step, ..., \violin@stop},
			yticklabel style={\violin@datalabelstyle},
		}
	\else
		\pgfplotsset{
			xticklabels/.expand once={\violin@labels},
			xtick/.expand once={\violin@start, \violin@step, ..., \violin@stop},
			xticklabel style={\violin@datalabelstyle},
		}
	\fi

	\begin{axis}[
		axis on top,
	]
		\@for\violin@plotindex:=\violin@indexes\do{
			\ifnum\violin@numofplots=1
				\pgfmathqparse{50}
			\else
				\pgfmathparse{int(\violin@counter*(100/(\violin@numofplots-1)))}
			\fi
			\let\violin@color@deg\pgfmathresult

			\pgfmathparse{1+\violin@counter*\violin@spacing}
			\let\violin@relativepos\pgfmathresult

			\addviolinplot[%
				index=\violin@plotindex,
				relative position=\violin@relativepos,
				color={\violin@color@primary!\violin@color@deg!\violin@color@secondary},
			]{\violin@filename}

			\pgfmathparse{int(\violin@counter+1)}
			\let\violin@counter\pgfmathresult
		}
	\end{axis}
}


% PGFplots-analogous alias
\let\violinplotsset\violinsetoptions

