Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

Box Plot in Matplotlib: ax.boxplot, Groups and Whiskers

How to draw a boxplot in Python with Matplotlib: grouped data, whis settings, colours and version-specific argument changes.

Written and maintained by CASRAI Editorial Board

Last updated

Short answer: in Matplotlib a box plot is drawn with Axes.boxplot. Pass one array for one box, a list of arrays for one box per group, or a 2D array for one box per column. This page is for researchers who need a box plot for a figure in a paper, and it covers the call, the whisker definition, grouped data from a CSV, per-box colours, and the argument changes between Matplotlib releases that older tutorials get wrong. The same function answers the searches ‘boxplot matplotlib’, ‘boxplot python’ and ‘box plot python’. Matplotlib documentation checked 2026-11-07.

What a box plot in Matplotlib is used for in research

A box plot summarises the distribution of a numerical variable per group: the box spans the first to third quartile, a line marks the median, whiskers extend from the box, and points beyond the whiskers are drawn individually as fliers. In research it is used to compare groups side by side (treatment arms, sites, batches) without assuming a normal distribution. For the reading rules themselves, see the guides on the IQR in a box plot and box-and-whisker plots compared.

Install or access Matplotlib

The Matplotlib installation page lists these official routes (read 2026-11-07):

python -m pip install -U matplotlib
conda install -c conda-forge matplotlib

The same page also lists pixi add matplotlib and uv add matplotlib, and suggests --prefer-binary if pip tries to compile from source. More detail is in the guide on installing Matplotlib with pip. Import it as shown in import matplotlib.pyplot as plt.

Step by step: draw a box plot

1. One box (boxplot python, the minimal case)

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(0)
values = rng.normal(loc=10, scale=2, size=100)

fig, ax = plt.subplots()
ax.boxplot(values)
plt.show()

Per the Axes.boxplot reference, x may be a 1D array (one box), a sequence of 1D arrays (one box each), or a 2D array (one box per column).

2. Several groups with labels

a = rng.normal(10, 2, 80)
b = rng.normal(12, 3, 80)
c = rng.normal(9, 1, 80)

fig, ax = plt.subplots()
ax.boxplot([a, b, c], tick_labels=['A', 'B', 'C'])
ax.set_ylabel('Measurement')
plt.show()

3. Box plot from a CSV, by group (matplotlib boxplot by group, multiple columns)

Matplotlib takes arrays, not a DataFrame grouping, so read the CSV with pandas and build one array per group. Dropping missing values per group before plotting keeps each array clean.

import pandas as pd

df = pd.read_csv('results.csv')          # columns: group, value
grouped = list(df.groupby('group'))
names = [name for name, _ in grouped]
groups = [g['value'].dropna().to_numpy() for _, g in grouped]

fig, ax = plt.subplots()
ax.boxplot(groups, tick_labels=names)
plt.show()

For several numeric columns at once, pass a 2D array (for example df[['c1', 'c2', 'c3']].to_numpy()) and you get one box per column. The pandas shortcut DataFrame.boxplot(column=..., by=...) draws one box per value of the by column and takes an ax argument, so it can target an existing Matplotlib axes (pandas documentation, read 2026-11-07).

4. Whiskers, notches, means and fliers

fig, ax = plt.subplots()
ax.boxplot([a, b, c],
           whis=(5, 95),        # whiskers at the 5th and 95th percentiles
           notch=True,
           showmeans=True,
           showfliers=False,
           tick_labels=['A', 'B', 'C'])
plt.show()

5. Colour each box

Boxes are lines by default. Set patch_artist=True to get fillable patches, then style the returned artists:

fig, ax = plt.subplots()
res = ax.boxplot([a, b, c], patch_artist=True, tick_labels=['A', 'B', 'C'])
for box, colour in zip(res['boxes'], ['#0072B2', '#E69F00', '#009E73']):
    box.set_facecolor(colour)
plt.show()

The return value is a dictionary of lists of Line2D objects with the keys boxes, medians, whiskers, caps, fliers and means. Style groups of elements with the boxprops, medianprops, whiskerprops, capprops, flierprops and meanprops arguments.

6. Horizontal box plot

ax.boxplot([a, b, c], orientation='horizontal')

The orientation argument was added in Matplotlib 3.10; in 3.11 the older vert argument is deprecated (see the version table below).

Output and how to read it

With the default whis=1.5, whiskers end at the lowest datum at or above Q1 – 1.5 x IQR and the highest datum at or below Q3 + 1.5 x IQR; points beyond are fliers. Other settings change what the whiskers mean:

whis value Whiskers end at
1.5 (default) The most extreme data within 1.5 x IQR of the box
A pair such as (5, 95) The given lower and upper percentiles of the data
(0, 100) The full range, so no fliers are drawn

Because the whisker rule is a choice, state it in the figure caption (for example ‘whiskers show the 5th to 95th percentile’). If Q1 equals Q3, the autorange=True option sets whis=(0, 100). A notch (notch=True) is a confidence interval around the median; the default uses a Gaussian asymptotic estimate, and bootstrap accepts a number of resamples (the reference suggests 1,000 to 10,000). Notches can extend beyond the box. The quartile interpolation method is not specified in the reference, so do not describe it in a methods section as if it were.

Version differences that break older tutorials

Argument Change in the Matplotlib documentation
tick_labels Renamed from labels in 3.9; labels is removed in 3.11
orientation Added in 3.10 ('vertical' or 'horizontal')
vert Deprecated in 3.11; use orientation
label Added in 3.9, for the legend entry

Troubleshooting

  • TypeError about an unexpected keyword labels: you are on Matplotlib 3.11 or later with code written for older versions. Use tick_labels.
  • A deprecation warning about vert: replace vert=False with orientation='horizontal'.
  • Boxes cannot be filled with a colour: set patch_artist=True first.
  • Fliers clutter the figure: showfliers=False hides them, or sym=''. Hiding them changes what readers see, so say so in the caption.
  • Group labels sit under the wrong boxes: positions defaults to 1 through N; if you pass custom positions, pass labels in the same order.
  • Check your version: import matplotlib; print(matplotlib.__version__).

Free alternatives

Tool Relation to Matplotlib
pandas DataFrame.boxplot Draws on Matplotlib; groups with by; accepts an ax argument
seaborn Builds on Matplotlib; see the guide on the seaborn boxplot
R / ggplot2 Separate ecosystem; see labelling a boxplot in R

FAQ

How do I make a boxplot in Python?

Call ax.boxplot(data) from Matplotlib on an axes created with plt.subplots(). Pass a list of arrays to get one box per group.

How do I draw a Matplotlib boxplot with multiple columns?

Pass a 2D array: Matplotlib draws one box per column. A list of 1D arrays gives the same result when the columns differ in length.

How do I make a Matplotlib boxplot by group?

Split the data into one array per group, for example with groupby in pandas, and pass the list to ax.boxplot with tick_labels. Alternatively use DataFrame.boxplot(column=..., by=...).

How do I change the whiskers?

Use whis: a number multiplies the IQR (default 1.5), a pair sets percentiles, and (0, 100) spans the full range.

Matplotlib or seaborn?

Seaborn builds on Matplotlib and works directly on DataFrames; Matplotlib gives lower-level control of every artist. See the seaborn boxplot guide; for distributions as histograms see histograms in Matplotlib.

Sources (read 2026-11-07)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Box Plot in Matplotlib: ax.boxplot, Groups and Whiskers

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →