Skip to content

pandas plot.barh

The same bar chart, turned so the labels fit.

Why is the bar chart with rotated labels so hard to read? Because text is horizontal and the labels are not. A vertical bar chart gives each category a sliver of width for its name, and the moment those names are words — "United Kingdom", "Report2Gov", "Administrative services" — matplotlib rotates them forty-five degrees and the chart becomes a puzzle.

.plot.barh() fixes it by rotating the chart instead of the text. Bars run left to right, categories stack down the side, and every label is written the way people read. The arguments are identical to plot.bar; only the axes swap.

Official documentation: pandas.DataFrame.plot.barh.

The arguments that earn their keep

s.plot.barh()                      # one bar per index entry, reading down
df.plot.barh(stacked=True)         # segments across, instead of up
df.plot.barh(figsize=(8, 12))      # tall, not wide — the opposite of plot.bar
s.sort_values().plot.barh()        # ascending puts the largest at the TOP

The one that surprises people is sort_values(). A horizontal bar chart draws the first row at the bottom and works upward, so an ascending sort puts the largest bar at the top — which is what you want, and the opposite of what you would do for plot.bar. Sorting descending here buries the winner at the bottom of the chart.

figsize also flips. Vertical bar charts need width; horizontal ones need height, roughly a quarter-inch per category before the labels start colliding.

A worked example, on real data

The same CO2 ranking as the plot.bar page, drawn the way the country names deserve:

import pandas as pd

url = 'https://raw.githubusercontent.com/owid/co2-data/master/owid-co2-data.csv'

df = pd.read_csv(url, usecols=['country', 'iso_code', 'year', 'co2'])

(df
 .loc[(df['year'] == 2023) & (df['iso_code'].str.len() == 3)]
 .nlargest(8, 'co2')
 .set_index('country')['co2']
 .sort_values()
 .plot.barh(figsize=(8, 5)))
country
Saudi Arabia       677.0
Indonesia          762.0
Iran               790.0
Japan              987.0
Russia            1733.0
India             3063.0
United States     4918.0
China            12172.0

Read the Series and the chart together: Saudi Arabia is first in the data and lowest on the chart, China is last in the data and at the top. That inversion is the whole trick, and it is why .sort_values() with no arguments — plain ascending — is the right call before nearly every barh.

Three mistakes people make

Sorting descending out of habit. It is the correct instinct for a table and for plot.bar, and it is backwards here. If your largest bar is at the bottom, drop the ascending=False.

Sizing it like a vertical chart. figsize=(12, 6) gives a horizontal bar chart a wide canvas and no room for rows, so the labels overlap. Grow the second number, not the first.

Using it for time. Horizontal bars read as a ranking, and a ranking has no natural order in time. Years down the left-hand side invite the reader to compare magnitudes rather than follow a trend, which is plot.line's job.

Where it shows up in Bamboo Weekly

plot.barh turns up in Bamboo Weekly #86: FEMA, Bamboo Weekly #112: Programming jobs and Bamboo Weekly #143: Phones in school. The common thread across all three is category names too long to sit under a vertical bar — disaster types, job titles, country policies.

Practice it

Work through a plot.barh exercise, with instant feedback and no signup required: practice.lernerpython.com/bamboo-weekly/plot-barh/

Go deeper

plot.bar is the vertical original and carries the fuller discussion of stacking. sort_values is what makes the ordering deliberate, and nlargest keeps the row count readable. value_counts produces the Series these charts usually want.

More Pandas videos on Python and Pandas with Reuven Lerner.

Bamboo Weekly is the practice. If you want the structured version — full courses with downloadable Jupyter notebooks, plus live Pandas office hours when you get stuck — that is LernerPython+Data. A paid Bamboo Weekly subscription is included with it.

See it on real data

Below are the 3 Bamboo Weekly exercises that use plot.barh on real-world data — try each one, then study the worked solution.

Part of the Pandas Methods Index. See also practice by skill.