Lesson 12
Horizontal Bar Charts
Use plt.barh when category names are long, set the bar thickness with height, and order the bars so the chart reads from the top down.
Turn a bar chart on its side and the category names get a whole line each instead of a cramped slot under a bar. That is the one real reason to prefer barh: long labels, or many categories. The numbers still run along the value axis, which is now the x axis.
Same data, turned sideways
plt.barh(y, width) takes the categories first and the numbers second, exactly like bar. What changes is which axis carries which: the categories run down the y axis and the values along the x axis, so xlabel now names the measurement.
import matplotlib.pyplot as plt
regions = ["Northgate", "Eastport", "Westfield", "Southbank"]
deliveries = [148, 96, 172, 63]
plt.barh(regions, deliveries, color="#2563EB")
plt.title("Deliveries by region")
plt.xlabel("deliveries")
plt.show()
print("busiest:", regions[deliveries.index(max(deliveries))])Output:
busiest: WestfieldThickness with height
bar has width; barh has height. Both mean the thickness of the bar in category slots, and both default to 0.8. Thinner bars make a crowded chart breathe.
import matplotlib.pyplot as plt
regions = ["Northgate", "Eastport", "Westfield", "Southbank"]
deliveries = [148, 96, 172, 63]
plt.barh(regions, deliveries, height=0.5, color="#7C3AED")
plt.title("Thinner bars, more white space")
plt.xlabel("deliveries")
plt.show()
print("bar takes width, barh takes height")Output:
bar takes width, barh takes heightReading order from the top
Sorted data on a horizontal chart comes out upside down, because the y axis counts upwards from the bottom. Sort ascending and the largest bar lands at the top, which is where a reader starts. gca().invert_yaxis() is the other route to the same place.
import matplotlib.pyplot as plt
regions = ["Northgate", "Eastport", "Westfield", "Southbank"]
deliveries = [148, 96, 172, 63]
ordered = sorted(zip(deliveries, regions))
widths = [value for value, _ in ordered]
labels = [name for _, name in ordered]
plt.barh(labels, widths, color="#7C3AED")
plt.title("Largest at the top")
plt.xlabel("deliveries")
plt.show()
print("drawn bottom to top:", ", ".join(labels))Output:
drawn bottom to top: Southbank, Eastport, Northgate, WestfieldWriting the value on the bar
When the exact number matters, print it at the end of the bar with plt.text. It takes an x position, a y position, and the string, and va="center" lines the text up with the middle of the bar.
import matplotlib.pyplot as plt
regions = ["Northgate", "Eastport", "Westfield", "Southbank"]
deliveries = [148, 96, 172, 63]
plt.barh(regions, deliveries, color="#7C3AED")
for position, value in enumerate(deliveries):
plt.text(value + 3, position, str(value), va="center")
plt.title("Deliveries by region")
plt.xlabel("deliveries")
plt.xlim(0, max(deliveries) * 1.15)
plt.show()
print("the extra xlim leaves room for the labels")Output:
the extra xlim leaves room for the labelsKey takeaways
-
barh puts categories on the y axis and values on the x axis
-
Reach for it when the category names are long or numerous
-
bar takes width, barh takes height, both in category slots
-
Sort ascending so the largest bar ends up at the top
-
Next: Stacked Bar Charts
-
Previous: Bar Charts
Loading playground…
Check your understanding
Horizontal Bar Charts Quiz
When is barh the better choice?
1 / 10