Matplotlib bar charts compare values across categories. Use bar() for vertical bars, barh() for horizontal bars, and stacked or grouped bars when each category has multiple series.
A good bar chart has a clear baseline, readable category labels, consistent colors, and enough spacing for the values being compared. Matplotlib gives you control over all of those pieces through the returned bar container and axes methods.
Bar charts work best when the x-axis contains categories rather than a continuous numeric range. If you are showing frequency distribution or binned numeric data, a histogram is usually a better choice. When category names are long or rankings matter more than time order, horizontal bars often communicate the comparison faster.
Create a basic Matplotlib bar chart
The core function is ax.bar(labels, values). It returns a container of bar artists that can be styled or labeled.
import matplotlib.pyplot as plt
labels = ["A", "B", "C", "D"]
values = [12, 18, 15, 24]
fig, ax = plt.subplots(figsize=(7, 4))
bars = ax.bar(labels, values)
ax.set_title("Category comparison")
ax.set_xlabel("Category")
ax.set_ylabel("Value")
ax.bar_label(bars)
plt.show()
The official pyplot.bar documentation and Axes.bar documentation list the parameters for width, bottom, alignment, colors, labels, and error bars.
Set bar colors, edges, and width
Use color for the fill color, edgecolor for the border, and width to control bar thickness. Keep colors meaningful rather than decorative when the chart supports a technical explanation.
fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(
labels,
values,
width=0.6,
color=["#2563eb", "#0f766e", "#f97316", "#ef4444"],
edgecolor="black",
)
ax.set_ylabel("Score")
plt.show()
If the labels are long, rotate them or switch to a horizontal chart. Python Pool’s Matplotlib xticks guide covers tick label positioning.
Add labels and grid lines
Bar labels help when exact values matter. Grid lines help readers compare heights, but they should stay subtle and behind the bars.
fig, ax = plt.subplots(figsize=(7, 4))
bars = ax.bar(labels, values, color="#2563eb")
ax.bar_label(bars, padding=3)
ax.grid(axis="y", linestyle="--", alpha=0.35)
ax.set_axisbelow(True)
plt.show()
The Matplotlib bar label demo shows more labeling patterns. Python Pool’s Matplotlib grid guide covers grid styling.
Create grouped bar charts
Grouped bars compare multiple series for each category. Offset the x positions so the bars sit side by side.
import numpy as np
labels = ["Q1", "Q2", "Q3", "Q4"]
sales = [20, 35, 30, 40]
profit = [8, 15, 12, 18]
x = np.arange(len(labels))
width = 0.35
fig, ax = plt.subplots(figsize=(8, 4))
ax.bar(x - width / 2, sales, width, label="Sales")
ax.bar(x + width / 2, profit, width, label="Profit")
ax.set_xticks(x, labels)
ax.legend()
plt.show()
Grouped bars are useful when every category has the same set of series. If there are too many series, the chart becomes hard to scan and a table or small multiples may be clearer. Keep the group order identical in every category so the legend remains easy to follow.
Create stacked bar charts
Stacked bars show how components add up to a total. The second bar call uses bottom to start each bar where the first series ends.
labels = ["A", "B", "C"]
part_one = [5, 8, 6]
part_two = [4, 3, 7]
fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(labels, part_one, label="Part one")
ax.bar(labels, part_two, bottom=part_one, label="Part two")
ax.set_ylabel("Total")
ax.legend()
plt.show()
Use stacked bars when the total and composition both matter. For many components, consider a different chart because small segments become difficult to compare.
Horizontal bar charts with barh()
Horizontal bars are better when category names are long. Use barh() and label the x-axis with the measured value.
names = ["Short label", "Long category name", "Another category"]
scores = [72, 88, 64]
fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(names, scores, color="#0f766e")
ax.set_xlabel("Score")
plt.show()
The official pyplot.barh documentation covers horizontal bars. Python Pool also has a full Matplotlib barh() guide.
Add error bars
For measurements with uncertainty, pass yerr to bar(). Error bars should be explained in the chart label or surrounding text.
values = [12, 18, 15, 24]
errors = [1.5, 2.0, 1.2, 2.5]
fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(labels, values, yerr=errors, capsize=5, color="#7c3aed")
ax.set_ylabel("Mean value")
plt.show()
For more uncertainty examples, see Python Pool’s Matplotlib errorbar guide.
Plot bars from a Pandas DataFrame
Pandas can call Matplotlib behind the scenes. This is convenient when the data already lives in a DataFrame.
import pandas as pd
frame = pd.DataFrame({
"sales": [20, 35, 30],
"profit": [8, 15, 12],
}, index=["Q1", "Q2", "Q3"])
ax = frame.plot.bar(figsize=(7, 4))
ax.set_ylabel("Amount")
plt.show()
The Pandas DataFrame.plot.bar documentation covers DataFrame-based bar charts.
Export the chart
Before exporting, check label rotation, figure size, and whether the legend overlaps the bars. Use savefig() when the chart is ready. Also inspect the exported file, because long labels can look fine in a notebook but get clipped in a saved PNG.
fig.savefig("bar-chart.png", dpi=160, bbox_inches="tight")
fig.savefig("bar-chart.pdf", bbox_inches="tight")
See Python Pool’s Matplotlib savefig() and Matplotlib figsize guides for export and sizing details.
Common bar chart mistakes
Too many categories. If labels crowd the x-axis, rotate the labels, use horizontal bars, or reduce the number of categories.
Unclear baseline. Bar charts usually need a clear zero baseline because readers compare lengths.
Too many colors. Use color to show meaning, not just decoration.
Wrong chart type. For distributions, use histograms instead of category bars. Python Pool’s Matplotlib 2D histogram and pie chart guides cover other comparison options.
Conclusion
Use bar() for vertical category comparisons, barh() for long labels, grouped bars for multiple series, and stacked bars for totals with components. Keep labels readable, use grids lightly, and export only after checking spacing and figure size.