Matplotlib barh(): Horizontal Bar Chart Guide

matplotlib.pyplot.barh() creates horizontal bar charts in Python. It is a strong choice when category names are long, when a ranking should read from top to bottom, or when a vertical chart would force labels to rotate.

Quick Answer

Use fig, ax = plt.subplots(), call ax.barh(categories, values), label the x-axis, and call ax.invert_yaxis() when the first category should appear at the top. Use bar_label() for values, left for stacks, and xerr for horizontal error bars.

Matplotlib barh horizontal bar chart with categories and values
barh() places category values along the x-axis, leaving more room for long labels and readable rankings.

The official barh() API reference documents the y positions, widths, heights, and left baseline. The horizontal bar chart example shows the common top-to-bottom ordering pattern.

Basic barh() Example

The object-oriented API keeps the axes handle available for labels, limits, and annotations.

import matplotlib.pyplot as plt

categories = ['API', 'CLI', 'Notebook']
values = [72, 48, 61]

fig, ax = plt.subplots()
bars = ax.barh(categories, values)
ax.set_xlabel('Requests')
ax.bar_label(bars, padding=4)
plt.tight_layout()
plt.show()

barh() accepts a scalar or a sequence for each of the category positions, widths, heights, and left offsets. The sequences must line up: one value should correspond to each category.

Order Categories From Top To Bottom

Matplotlib’s default y-axis direction can make the first category appear at the bottom. Sorting the data and inverting the y-axis gives a readable ranking.

import matplotlib.pyplot as plt

categories = ['API', 'CLI', 'Notebook']
values = [72, 48, 61]

fig, ax = plt.subplots()
bars = ax.barh(categories, values, height=0.55,
               color=['#0f766e', '#f59e0b', '#ef4444'])
ax.bar_label(bars, fmt='%.0f')
ax.invert_yaxis()
plt.show()

Use ax.invert_yaxis(), not a made-up setter such as set_yinverted(). If the order carries meaning, sort the source data before plotting so the chart remains reproducible.

Python Pool infographic showing categories, values, y positions, heights, and a horizontal bar chart
Horizontal data: Categories, values, y positions, heights, and a horizontal bar chart.

Sort Data Before Plotting

Keep labels and values together while sorting. Sorting one list without the other is a common cause of misleading charts.

import matplotlib.pyplot as plt

items = [('Notebook', 61), ('API', 72), ('CLI', 48)]
items = sorted(items, key=lambda item: item[1])
labels = [item[0] for item in items]
values = [item[1] for item in items]

fig, ax = plt.subplots()
ax.barh(labels, values)
ax.invert_yaxis()
plt.show()

For descending charts, reverse the sorted sequence or invert the axis according to the visual order you want. Write that decision in code so a later data refresh does not silently change the story.

Add Value Labels And Styling

The returned BarContainer can be passed to ax.bar_label(). Use a small, consistent color set and leave enough space for text.

For long labels, increase the figure width, use a smaller but readable font, or wrap labels before plotting. Do not hide labels by shrinking the whole figure until the text becomes inaccessible on a phone.

Build Stacked Horizontal Bars

Pass the width of the earlier segment through left to start the next segment at the correct x position.

import matplotlib.pyplot as plt

categories = ['API', 'CLI', 'Notebook']
first = [50, 30, 45]
second = [22, 18, 16]

fig, ax = plt.subplots()
ax.barh(categories, first, label='completed')
ax.barh(categories, second, left=first, label='pending')
ax.legend()
plt.show()

Every left value must represent the cumulative width for that category. A single scalar is fine for one common baseline; a sequence is needed when each category has a different previous segment.

Python Pool infographic mapping horizontal bars through tick labels, sorting, annotations, and axes
Category labels: Horizontal bars through tick labels, sorting, annotations, and axes.

Show Error Bars With xerr

Because the numeric axis is horizontal, uncertainty in the bar width is represented with xerr. The error sequence should align with the values.

import matplotlib.pyplot as plt

categories = ['API', 'CLI', 'Notebook']
values = [72, 48, 61]
errors = [4, 3, 5]

fig, ax = plt.subplots()
ax.barh(categories, values, xerr=errors, capsize=4)
ax.set_xlabel('Requests plus or minus error')
plt.show()

Error bars communicate measurement uncertainty or variation; they should not be used as decorative whiskers. Add a note or legend when readers need to know what the error value represents.

Layout And Readability

Use figsize, ax.set_xlim(), and plt.tight_layout() or fig.tight_layout() to keep labels inside the figure. With very long category names, constrained_layout=True can also help.

For many categories, reduce clutter by selecting the relevant subset, grouping low-volume categories, or using a scrollable interactive view. A chart with every available category is not automatically more informative.

barh() Compared With bar()

bar() is vertical and maps categories to x positions; barh() is horizontal and maps categories to y positions. Choose the orientation that makes the labels and comparison easiest to scan. Both functions return a BarContainer that can be labeled with bar_label().

For complex figures, keep explicit ax variables and avoid relying on the global pyplot state. The related Matplotlib gca() guide explains why explicit axes are often easier to maintain.

Python Pool infographic comparing grouped, stacked, offsets, legends, and multiple series
Grouped horizontal bars: Grouped, stacked, offsets, legends, and multiple series.

Common barh() Problems

  • Categories and values have different lengths.
  • The first category appears at the bottom because the y-axis was not inverted.
  • Long labels are clipped because the figure is too narrow.
  • Stacked segments overlap because left is not cumulative.
  • Value labels are clipped because the x-axis has no extra margin.

Start with a small, known dataset, verify the order and units, then add styling. This makes a horizontal chart easier to test and less likely to communicate a false comparison.

Important barh() Arguments

The y argument supplies category positions or labels, and width supplies the numeric extent of each bar. height controls bar thickness, left shifts the baseline, and align controls how a bar is positioned around its y coordinate. Most visual properties, such as alpha, edge color, and hatch, are forwarded to the underlying Rectangle artists.

Use a sequence when each category needs a different height or baseline. A scalar is broadcast to every bar. If a sequence has the wrong length, the resulting error is usually a data-shape problem rather than a Matplotlib styling problem.

Negative Values And Zero

Horizontal bars can extend left when a width is negative. This is useful for diverging comparisons, but label placement and x-axis limits need more care. Include a visible zero line when readers need to distinguish positive and negative values.

Zero-width bars may be invisible even though their category labels are present. Add a value label or a small minimum display width only when that choice is explained, because visual exaggeration can distort a comparison.

Python Pool infographic testing negative widths, long labels, missing values, layout, and savefig
Barh checks: Negative widths, long labels, missing values, layout, and savefig.

Ticks, Units, And Accessible Labels

Always label the numeric axis with its unit, such as milliseconds, requests, dollars, or percent. A chart title alone rarely tells a reader whether a value is a count, rate, or measurement.

Use color as a secondary cue rather than the only way to distinguish categories. Bar labels, hatching, direct annotations, and a legend help readers with color-vision differences and also improve scanning on small screens.

Dates And Categorical Data

For dates or times, decide whether the categories are labels or actual numeric date coordinates. If the y positions represent dates, use the matching Matplotlib units and format the axis deliberately. For ordinary named categories, a list of strings is simpler and keeps the intent obvious.

Do not mix a category list from one data frame with values from a differently sorted frame. Build one sorted table or list of records, then derive both labels and widths from that same sequence.

Choose A Figure Size For The Labels

Long category names need horizontal space on the left, while value labels need space on the right. Increase the figure width before reducing the font. When exporting, test the saved image at its actual display size and check that the first and last labels are not clipped.

For a responsive article, prefer an image with readable labels and include the underlying data or code in the page as text. The image should support the explanation, not be the only place where the values are available.

Frequently Asked Questions

What does Matplotlib barh() do?

barh() creates a horizontal bar plot. The category positions are placed on the y-axis and the bar widths represent values along the x-axis.

How do I put the largest bar at the top?

Sort the categories and values in the order you want, then call ax.invert_yaxis() so the first category is displayed at the top of the chart.

How do I add numbers to horizontal bars?

Keep the BarContainer returned by ax.barh() and pass it to ax.bar_label(). Adjust padding or the x-axis limit when labels need extra room.

How do I make a stacked horizontal bar chart?

Call barh() more than once with the same categories and pass the cumulative previous widths through the left argument.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted