Bars and histograms answer the two most common questions about data: how do groups compare, and how are values spread?
A bar chart compares a number across categories. ax.bar(categories, heights) accepts strings directly as x positions, and ax.barh draws horizontal bars, which are easier to read when category names are long. Useful options: width=, color=, edgecolor=, and bottom= to stack one series on top of another.
Grouped bars need a little arithmetic: plot each series at x - w/2 and x + w/2 where x = np.arange(n), then set the tick labels to the category names.
A histogram is different: it takes raw values, cuts their range into bins and counts how many fall in each. ax.hist(values, bins=30) returns three things: the counts, the bin edges (one more than the counts) and the bar patches.
binscan be an integer, an explicit list of edges, or a rule such as"auto".density=Truerescales so the bars' total area is 1, which lets you compare samples of different sizes.histtype="step"draws outlines, good for overlaying two distributions.
The number of bins changes the story a histogram tells: too few hides structure, too many shows noise. Try a few values before drawing conclusions.
Bars encode values by length, so the value axis of a bar chart should start at zero; a truncated axis exaggerates differences. Matplotlib does this by default for bars.
Example
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9, 3.5))
langs = ["Python", "Go", "Rust"]
ax1.bar(langs, [42, 18, 12], color="tab:blue")
ax1.set_ylabel("Projects")
rng = np.random.default_rng(1)
values = rng.normal(loc=170, scale=8, size=1000)
counts, edges, patches = ax2.hist(values, bins=20, edgecolor="white")
print(len(counts), len(edges)) # 20 21
print(int(counts.sum())) # 1000
print(ax1.get_ylim()[0]) # 0.0 (bars start at zero)
fig.savefig("bars.png")Remember
bar/barhcompare categories; strings work as x positionshistbins raw values and returns counts, edges and patches- Try several bin counts; use
density=Trueto compare different-sized samples
Watch out for
- Passing already-counted data to
hist; usebarfor counts you computed yourself.