Written and maintained by CASRAI Editorial Board
Last updated
seaborn.barplot() (usually called as sns.barplot) draws one bar per category, where the bar height is an estimate of a numeric variable, the mean by default, and a line on each bar shows the uncertainty of that estimate. The detail most tutorials skip is what that line is: by default it is a 95% bootstrapped confidence interval, not a standard deviation. This guide shows the syntax step by step, explains each error-bar option, and lists the argument changes that break older snippets. Everything below was checked against the seaborn documentation on 2026-10-29.
What sns.barplot shows in research (and what it does not)
A bar plot summarises a numeric variable for each level of a categorical variable. According to the seaborn documentation, each bar is an aggregate or estimate of a numeric variable, its height is set by the estimator (mean by default), and the error bar around it represents the uncertainty of that estimate. Bar plots include 0 in the axis range, so they suit cases where 0 is a meaningful baseline.
A bar plot shows only the aggregate, not the distribution behind it. The seaborn documentation recommends boxplot() or violinplot() when you need to show spread, and pointplot() when 0 is not meaningful and you mainly want to compare levels. See the CASRAI guides on seaborn boxplots and seaborn violin plots, and the overview of types of graphs in statistics for choosing between chart types.
Install or access
Install seaborn from the Python Package Index with pip install seaborn. The installation page also lists an optional extra, pip install seaborn[stats], and states that numpy, pandas and matplotlib are mandatory dependencies; check that page for the Python versions the current release supports. The conventional imports are:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
Step by step: build a bar plot with sns.barplot
The signature, from the current API reference, is seaborn.barplot(data=None, *, x=None, y=None, hue=None, order=None, hue_order=None, estimator='mean', errorbar=('ci', 95), n_boot=1000, seed=None, units=None, weights=None, orient=None, color=None, palette=None, saturation=0.75, fill=True, hue_norm=None, width=0.8, dodge='auto', gap=0, log_scale=None, native_scale=False, formatter=None, legend='auto', capsize=0, err_kws=None, ax=None, **kwargs). The steps below use a small table so they run without downloading anything.
- Create a data frame in long format, one row per observation:
df = pd.DataFrame({ 'group': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'], 'sex': ['F', 'M', 'F', 'M', 'F', 'M', 'F', 'M', 'F'], 'score': [4.1, 5.0, 4.6, 6.2, 5.8, 6.5, 3.9, 4.4, 4.0], }) - Draw the basic plot. Pass the table as
dataand name the categorical and numeric columns:sns.barplot(data=df, x='group', y='score') plt.show()Each bar is the mean of
scorefor one group, with a 95% confidence interval. - Set the category order with
order:sns.barplot(data=df, x='group', y='score', order=['C', 'B', 'A']). - Make the bars horizontal by putting the numeric variable on x:
sns.barplot(data=df, x='score', y='group'). Theorientargument accepts'v','h','x'or'y'(the last two since v0.13.0) when the orientation cannot be inferred. - Split bars by a second variable with
hue:sns.barplot(data=df, x='group', y='score', hue='sex'). The defaultdodge='auto'(added in v0.13.0) places the hue levels side by side whenhueis crossed with the categorical axis variable, and does not dodge whenhueis the same variable asx. - Change the statistic with
estimator, for exampleestimator='median', or pass a callable. - Choose the error bar with
errorbar(next section) and add end caps withcapsize:sns.barplot(data=df, x='group', y='score', errorbar='sd', capsize=0.2). Passerrorbar=Noneto hide the bars. - Style it.
paletteandcolorcontrol fill colours; see seaborn color palettes. Because seaborn draws onto matplotlib axes, labels and titles come from matplotlib, for exampleplt.title('Mean score by group'). The relationship between the two libraries is covered in seaborn vs matplotlib.
Output and how to read it: what the error bars mean
The errorbar parameter (new in v0.12.0) accepts 'ci', 'pi', 'se', 'sd', a (method, level) tuple, a callable, or None. The default is ('ci', 95). The seaborn error-bars tutorial defines them as follows:
| Setting | What the line shows |
|---|---|
'sd' |
±1 standard deviation around the estimate by default; describes spread of the data |
'se' |
±1 standard error of the mean, the standard deviation divided by √n; describes uncertainty of the estimate |
'pi' |
95% percentile interval of the data, from the 2.5th to the 97.5th percentile |
'ci' (default) |
95% confidence interval, the percentile interval of a bootstrap distribution obtained by resampling the data with replacement |
Two practical consequences follow. First, because the default interval is bootstrapped, it is random: n_boot sets the number of resampling iterations (default 1000) and seed makes the interval reproducible, so set seed for any figure you publish. Second, 'sd' and 'ci' answer different questions, so name the choice in the figure caption, for example “Bars show means; error bars show 95% bootstrapped confidence intervals (1000 resamples)”. Two bars whose error bars overlap are not automatically a “no difference” result; the plot summarises each group separately and is not a hypothesis test.
Troubleshooting: old snippets, deprecation warnings and axis problems
| Symptom | Cause and fix (per the API reference) |
|---|---|
ci=... is ignored or warns |
ci was deprecated in v0.12.0. Use errorbar, for example errorbar=('ci', 95) or errorbar='sd'. |
errcolor or errwidth warns |
Deprecated in v0.13.0. Use err_kws={'color': 'black'} and err_kws={'linewidth': 2}; err_kws takes a dictionary of line properties. |
Bars with hue are not side by side |
Since v0.13.0 the default is dodge='auto', which dodges only when the orient variable is crossed with hue; if hue is the same variable as x, bars are not dodged. Set dodge=True or False explicitly to force a behaviour. |
| Need to weight observations | weights was added in v0.13.1. |
native_scale, gap, fill, legend not recognised |
These arguments were added in v0.13.0; upgrade seaborn. |
Free alternatives
| Tool | Function | Note from its documentation |
|---|---|---|
| Matplotlib | Axes.bar / plt.bar |
“Make a bar plot”; you supply the bar positions and heights yourself, so aggregation and error bars are your responsibility |
| Plotly (Python) | px.bar() |
Plotly Express function for bar charts, documented on the Plotly Python bar-charts page |
For line-based comparisons of trends, see seaborn line plots.
FAQ
What does sns.barplot plot by default?
It plots the mean of the numeric variable for each category, with a 95% bootstrapped confidence interval as the error bar.
How do I show standard deviation instead of a confidence interval?
Pass errorbar='sd'. To show the standard error instead, pass errorbar='se'.
How do I remove the error bars?
Pass errorbar=None.
Why does my old code with ci= or errwidth= warn?
ci was replaced by errorbar in v0.12.0, and errcolor and errwidth were replaced by err_kws in v0.13.0.
Should I use a bar plot or a box plot?
Use a bar plot when you want to compare estimates and 0 is meaningful. Use a box plot or violin plot when the distribution matters, because a bar shows only the aggregate.
Sources (official documentation, checked 2026-10-29)
- seaborn.barplot API reference, seaborn.pydata.org: https://seaborn.pydata.org/generated/seaborn.barplot.html
- Statistical estimation and error bars, seaborn.pydata.org: https://seaborn.pydata.org/tutorial/error_bars.html
- Installing seaborn, seaborn.pydata.org: https://seaborn.pydata.org/installing.html
- matplotlib.axes.Axes.bar, matplotlib.org: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.bar.html
- Bar charts in Python, plotly.com: https://plotly.com/python/bar-charts/







