Violin plots

Matplotlib Basics

2 min read

Published Oct 5 2025


15
0
0
0

ChartsGraphsMatplotlibNumPyPandasPythonVisualisation

A violin plot combines a box plot and a kernel density plot (KDE) — it shows:

  • The distribution shape (density) of the data on each side.
  • The median and interquartile range (like a box plot).
  • Possible multiple datasets side by side.

It’s ideal for comparing data distributions and spread between groups.


Syntax:

plt.violinplot(dataset, positions=None, vert=True, widths=0.5, showmeans=False, showextrema=True, showmedians=False,bw_method=None)

Parameters:

  • dataset = Array-like data or list of datasets
  • positions = X-axis positions of violins
  • vert = Vertical (True) or horizontal (False)
  • widths = Width of each violin
  • showmeans = Show mean marker
  • showextrema = Show min/max bars
  • showmedians = Show median line
  • bw_method = Controls smoothing of KDE (e.g., 'scott', 'silverman', or float)



Basic violin plot example

import matplotlib.pyplot as plt
import numpy as np

data = np.random.normal(0, 1, 100)

plt.violinplot(data)
plt.title("Basic Violin Plot")
plt.show()

Displays one violin — vertical, centred at x = 1.


matplotlib violin chart basic example




Multiple violin plots

Pass multiple datasets as a list (or 2D array):

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

plt.violinplot(data)
plt.title("Multiple Violin Plots")
plt.show()

matplotlib violin chart multiple example




Add labels

By default, violin plots have no x-axis labels — you can add them manually:

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

plt.violinplot(data)
plt.xticks([1, 2, 3], ['A', 'B', 'C'])
plt.title("Violin Plots with Labels")
plt.show()

matplotlib violin chart with labels example




Show median, mean, and extremes

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

plt.violinplot(data, showmeans=True, showmedians=True, showextrema=True)
plt.xticks([1, 2, 3], ['A', 'B', 'C'])
plt.title("Violin Plots with Mean and Median")
plt.show()

  • Mean: typically a dot or horizontal line.
  • Median: bold centre line.
  • Extrema: thin top/bottom lines.

matplotlib violin chart mean median example




Horizontal violin plots

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

plt.violinplot(data, vert=False, showmedians=True)
plt.yticks([1, 2, 3], ['A', 'B', 'C'])
plt.title("Horizontal Violin Plots")
plt.show()

matplotlib violin chart horizontal example




Adjust widths and positions

You can manually set the positions and relative widths of violins:

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

# skip position 3
positions = [1, 2, 4]

plt.violinplot(data, positions=positions, widths=0.7, showmedians=True)
plt.xticks(positions, ['A', 'B', 'C'])
plt.title("Custom Positions and Widths")
plt.show()

matplotlib violin chart positions width example




Customise appearance

The violinplot function returns a dictionary-like object with components (bodies, cmeans, cmedians, etc.), so you can modify their styles individually:

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

parts = plt.violinplot(data, showmeans=True, showmedians=True)

for pc in parts['bodies']:
    pc.set_facecolor("#FFC9D6")
    pc.set_edgecolor('black')
    pc.set_alpha(0.7)

plt.title("Styled Violin Plots")
plt.xticks([1, 2, 3], ['A', 'B', 'C'])
plt.show()

matplotlib violin chart styled example




Change smoothing (bandwidth) of KDE

The bw_method parameter controls how smooth the violins are:

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

plt.violinplot(data, bw_method=0.3, showmedians=True)
plt.title("Violin Plots with Custom Bandwidth")
plt.show()

Smaller bw_method = more jagged, larger = smoother.


matplotlib violin chart custom band width example




Overlay box plot or scatter points

You can combine violin plots with box plots or raw data points for more detail:

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

plt.violinplot(data, showmedians=True)
plt.boxplot(data, positions=[1, 2, 3], widths=0.1)
plt.xticks([1, 2, 3], ['A', 'B', 'C'])
plt.title("Violin + Box Plot Overlay")
plt.show()

matplotlib violin chart box plot overlay example

Or scatter points:

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

for i, d in enumerate(data, start=1):
    plt.scatter(np.random.normal(i, 0.05, len(d)), d, alpha=0.3)
    
plt.violinplot(data, showmedians=True)
plt.title("Violin Plot with Raw Data Overlay")
plt.show()

matplotlib violin chart scatter overlay example




Full styled example

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.8, 100)]

parts = plt.violinplot(
    data,
    showmeans=True,
    showmedians=True,
    showextrema=False,
    bw_method=0.3
)

colors = ['#99ccff', '#ff9999', '#99ff99']
for pc, color in zip(parts['bodies'], colors):
    pc.set_facecolor(color)
    pc.set_edgecolor('black')
    pc.set_alpha(0.8)

plt.xticks([1, 2, 3], ['A', 'B', 'C'])
plt.title("Styled Violin Plots with Mean and Median")
plt.show()

matplotlib violin chart full styled example
© 2025 SimpleSteps.guide
AboutFAQPoliciesContact