Skip to content

How to order categorical levels in a bar plot in Seaborn (with Code)

The Short Answer (TL;DR)

Pass an explicit list to the order argument of sns.barplot to set the displayed category sequence. The order controls positions; the estimator still calculates the mean of the observations within each category.

import pandas as pd, seaborn as sns
data = pd.DataFrame({"tier": ["large", "small", "medium"] * 3, "value": [9, 3, 6, 10, 5, 8, 11, 4, 7]})
sns.barplot(data=data, x="tier", y="value", order=["small", "medium", "large"], estimator="mean", errorbar=None, color="steelblue")

Detailed Implementation

This example uses synthetic data and does not need a network connection. Install the recorded package versions in a separate Python environment before running it.

python -m pip install numpy==2.5.4 pandas==3.0.6 matplotlib==3.11.2 seaborn==0.13.2
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

data = pd.DataFrame({
    "tier": ["large", "small", "medium"] * 3,
    "value": [9, 3, 6, 10, 5, 8, 11, 4, 7],
})
order = ["small", "medium", "large"]
if set(data["tier"].unique()) != set(order):
    raise ValueError("The order must include every observed category.")
means = data.groupby("tier")["value"].mean().reindex(order)
fig, ax = plt.subplots(figsize=(5.8, 3.6), layout="constrained")
sns.barplot(data=data, x="tier", y="value", order=order,
            estimator="mean", errorbar=None, color="steelblue", ax=ax)
ax.bar_label(ax.containers[0], fmt="%.1f", padding=3)
ax.set(xlabel="Tier", ylabel="Mean synthetic measurement",
       title="Explicit category order; uncertainty intervals omitted", ylim=(0, 12))
fig.savefig("ordered-category-bars.png", dpi=160)
plt.show()

The bars appear as small, medium and large, with heights 4, 7 and 10. Each bar summarizes three observations, and the title states that uncertainty intervals are omitted.

Does order sort observations or recompute means?

The argument chooses where categories appear along the axis. It does not change the rows or their within-category means. Here the input first mentions large, but the displayed sequence is small, medium and large.

What happens if a category is omitted?

An explicit order can exclude categories from the display. The full example checks that the observed categories and the supplied list contain the same labels, so an accidental omission raises an error rather than silently hiding a group.

Why are there no error bars?

The example sets errorbar=None to isolate the ordering task. The bars summarize three observations per tier, and omitted intervals do not imply zero sampling uncertainty. Choose and describe an appropriate interval when uncertainty is part of the comparison.

Mathematical Context

With the mean estimator, a bar for category g has height equal to the sum of that category's values divided by its observation count. The small values 3, 5 and 4 average to 4; medium values 6, 8 and 7 average to 7; large values 9, 10 and 11 average to 10. Reordering categories permutes the displayed positions while preserving these three estimates. A barplot summarizes a numeric response; a countplot instead displays frequencies.

\[ \bar{y}_g=\frac{1}{n_g}\sum_{i:g_i=g} y_i \]

Reproducibility

Executed with Python 3.12.14; numpy 2.5.4, pandas 3.0.6, matplotlib 3.11.2, seaborn 0.13.2. Automated checks confirm the stated output properties.

Primary documentation

Related guides

Related technical references