Skip to content

Matplotlib - Bar Plot

A bar chart (or bar graph) is a fundamental visualization used to represent categorical data with rectangular bars. The length or height of each bar is proportional to the value it represents. Bar charts are excellent for comparing discrete values across different categories.

Matplotlib provides the ax.bar() method for creating vertical bar charts and ax.barh() for horizontal bar charts.

ax.bar(x, height, width=0.8, bottom=None, align='center', **kwargs)
  • x: Sequence of scalars or strings representing the x-coordinates (positions) or category labels of the bars.
  • height: Scalar or sequence of scalars representing the height(s) of the bars.
  • width: Scalar or array-like (default 0.8). The width(s) of the bars.
  • bottom: Scalar or array-like (default None). The y-coordinate(s) of the bar bases (used for stacked charts).
  • align: {‘center’, ‘edge’}. Alignment of the bars relative to the x coordinates.
  • color, edgecolor, linewidth, label, alpha: Standard plotting keyword arguments.

Example: Enrollment in different courses.

import matplotlib.pyplot as plt
# Data
courses = ['C', 'C++', 'Java', 'Python', 'PHP']
students = [23, 17, 35, 29, 12]
fig, ax = plt.subplots(figsize=(7, 5))
# Create the bar chart
bars = ax.bar(courses, students, color='skyblue', edgecolor='black')
# Add labels and title
ax.set_xlabel('Programming Language')
ax.set_ylabel('Number of Students Enrolled')
ax.set_title('Course Enrollment')
ax.grid(axis='y', linestyle='--', alpha=0.7)
# Optional: Add data labels on top of bars
ax.bar_label(bars, padding=3)
plt.show()

To compare multiple series across the same categories, you can create grouped bar charts. This involves calculating shifted x-positions for the bars of each series.

import matplotlib.pyplot as plt
import numpy as np
# Data: Sales figures for 3 products over 4 quarters
labels = ['Q1', 'Q2', 'Q3', 'Q4']
product_a_sales = [30, 25, 50, 20]
product_b_sales = [40, 23, 51, 17]
product_c_sales = [35, 22, 45, 19]
# Calculate bar positions
x = np.arange(len(labels)) # Label locations [0, 1, 2, 3]
width = 0.25 # Width of each bar
fig, ax = plt.subplots(figsize=(10, 6))
rects1 = ax.bar(x - width, product_a_sales, width, label='Product A', color='cornflowerblue')
rects2 = ax.bar(x, product_b_sales, width, label='Product B', color='lightcoral')
rects3 = ax.bar(x + width, product_c_sales, width, label='Product C', color='lightgreen')
# Add labels, title, and legend
ax.set_ylabel('Sales Figures')
ax.set_title('Quarterly Sales by Product')
ax.set_xticks(x) # Set x-tick positions to the center of the groups
ax.set_xticklabels(labels)
ax.legend()
ax.grid(axis='y', linestyle='--', alpha=0.7)
# Add data labels
ax.bar_label(rects1, padding=3)
ax.bar_label(rects2, padding=3)
ax.bar_label(rects3, padding=3)
fig.tight_layout()
plt.show()

Stacked bar charts show the contribution of different series to a total within each category. You use the bottom parameter in subsequent ax.bar() calls to stack bars on top of each other.

import matplotlib.pyplot as plt
import numpy as np
# Data: Contributions of two groups to scores over 5 categories
labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = np.array([20, 35, 30, 35, 27])
women_means = np.array([25, 32, 34, 20, 25])
width = 0.5 # Width of the bars
fig, ax = plt.subplots(figsize=(8, 6))
# Plot Men's scores (bottom layer)
bar1 = ax.bar(labels, men_means, width, label='Men', color='dodgerblue')
# Plot Women's scores on top of Men's scores
bar2 = ax.bar(labels, women_means, width, bottom=men_means, label='Women', color='hotpink')
ax.set_ylabel('Scores')
ax.set_title('Scores by Group and Gender (Stacked)')
ax.legend()
ax.grid(axis='y', linestyle='--', alpha=0.7)
# Add data labels (optional, can get crowded)
# ax.bar_label(bar1, label_type='center')
# ax.bar_label(bar2, label_type='center')
# ax.bar_label(bar2) # Labels for the top of the stack
plt.show()

ax.barh(y, width, height=0.8, left=None, ...) works similarly to ax.bar, but creates horizontal bars. This is often better when you have long category labels.