Matplotlib bar() / barh() 函数
bar() 用于绘制垂直柱状图,barh() 用于绘制水平柱状图。
柱状图用于展示分类数据的数量对比,每个分类用一根柱子表示其数值大小。
函数定义
bar() - 垂直柱状图
matplotlib.pyplot.bar(x, height, width=0.8, bottom=0, *, align='center',
**kwargs)
barh() - 水平柱状图
matplotlib.pyplot.barh(y, width, height=0.8, left=0, *, align='center',
**kwargs)
Axes 接口
Axes.bar(x, height, width=0.8, bottom=0, *, align='center', **kwargs) Axes.barh(y, width, height=0.8, left=0, *, align='center', **kwargs)
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| x / y | array-like | 柱子的位置坐标(垂直用 x,水平用 y) |
| height / width | array-like | 柱子的高度(垂直)或宽度(水平),即数据值 |
| width(bar)/ height(barh) | float 或 array-like | 柱子的宽度/高度,默认 0.8 |
| bottom / left | float 或 array-like | 柱子底部的起始位置,默认 0。可用于绘制堆叠柱状图 |
| align | str | 柱子与 x/y 坐标的对齐方式:'center'(默认)或 'edge' |
| color | color 或 list | 柱子颜色,可为单一颜色或颜色列表 |
| edgecolor | color | 柱子边框颜色 |
| linewidth / lw | float | 柱子边框宽度 |
| tick_label | array-like | 柱子的刻度标签,与 x 位置一一对应 |
| label | str | 图例标签(用于分组柱状图) |
| alpha | float | 透明度 |
| hatch | str | 填充图案:'/'、'\'、'|'、'-', '+'、'x'、'o'、'*' |
bar_label() 补充说明
bar_label() 用于在柱子上直接显示数值标签。
Axes.bar_label(container, labels=None, *, fmt=None, label_type='edge',
padding=0, **kwargs)
bar() 和 barh() 返回一个
BarContainer对象,可传给 bar_label() 来添加数值标签。这是 Matplotlib 3.4+ 推荐的做法。
使用示例
示例 1:基本垂直柱状图
实例
import matplotlib.pyplot as plt
# 分类标签和数据
categories = ['Python', 'Java', 'JavaScript', 'C++', 'Go']
values = [85, 72, 68, 55, 42]
fig, ax = plt.subplots(layout='constrained')
# 绘制柱状图
bars = ax.bar(categories, values,
color=['#3498db', '#e74c3c', '#f39c12', '#2ecc71', '#9b59b6'],
edgecolor='white', linewidth=1)
# 在柱子上显示数值
ax.bar_label(bars, fmt='%d', padding=3)
ax.set_title('Programming Language Popularity')
ax.set_ylabel('Score')
ax.set_ylim(0, 100)
ax.grid(axis='y', alpha=0.3)
plt.show()
# 分类标签和数据
categories = ['Python', 'Java', 'JavaScript', 'C++', 'Go']
values = [85, 72, 68, 55, 42]
fig, ax = plt.subplots(layout='constrained')
# 绘制柱状图
bars = ax.bar(categories, values,
color=['#3498db', '#e74c3c', '#f39c12', '#2ecc71', '#9b59b6'],
edgecolor='white', linewidth=1)
# 在柱子上显示数值
ax.bar_label(bars, fmt='%d', padding=3)
ax.set_title('Programming Language Popularity')
ax.set_ylabel('Score')
ax.set_ylim(0, 100)
ax.grid(axis='y', alpha=0.3)
plt.show()
示例 2:分组柱状图
实例
import matplotlib.pyplot as plt
import numpy as np
# 分组数据
labels = ['Q1', 'Q2', 'Q3', 'Q4']
product_a = [120, 135, 148, 162]
product_b = [90, 105, 115, 130]
x = np.arange(len(labels)) # x 位置:[0, 1, 2, 3]
width = 0.35 # 每个柱子的宽度
fig, ax = plt.subplots(layout='constrained')
# 第一组柱子(偏移 -width/2)
bars1 = ax.bar(x - width/2, product_a, width,
label='Product A', color='steelblue', edgecolor='white')
# 第二组柱子(偏移 +width/2)
bars2 = ax.bar(x + width/2, product_b, width,
label='Product B', color='coral', edgecolor='white')
# 添加数值标签
ax.bar_label(bars1, padding=3, fmt='%d')
ax.bar_label(bars2, padding=3, fmt='%d')
ax.set_title('Quarterly Sales Comparison')
ax.set_ylabel('Sales (units)')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()
ax.grid(axis='y', alpha=0.3)
plt.show()
import numpy as np
# 分组数据
labels = ['Q1', 'Q2', 'Q3', 'Q4']
product_a = [120, 135, 148, 162]
product_b = [90, 105, 115, 130]
x = np.arange(len(labels)) # x 位置:[0, 1, 2, 3]
width = 0.35 # 每个柱子的宽度
fig, ax = plt.subplots(layout='constrained')
# 第一组柱子(偏移 -width/2)
bars1 = ax.bar(x - width/2, product_a, width,
label='Product A', color='steelblue', edgecolor='white')
# 第二组柱子(偏移 +width/2)
bars2 = ax.bar(x + width/2, product_b, width,
label='Product B', color='coral', edgecolor='white')
# 添加数值标签
ax.bar_label(bars1, padding=3, fmt='%d')
ax.bar_label(bars2, padding=3, fmt='%d')
ax.set_title('Quarterly Sales Comparison')
ax.set_ylabel('Sales (units)')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()
ax.grid(axis='y', alpha=0.3)
plt.show()
示例 3:堆叠柱状图
实例
import matplotlib.pyplot as plt
categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May']
income = [5000, 5200, 4800, 5500, 6000]
expense = [3000, 3500, 3200, 4000, 4200]
fig, ax = plt.subplots(layout='constrained')
# 第一层柱子(底部)
bars_income = ax.bar(categories, income,
label='Income', color='#2ecc71', edgecolor='white')
# 第二层柱子(堆叠在第一层之上)
bars_expense = ax.bar(categories, expense, bottom=income,
label='Expense', color='#e74c3c', edgecolor='white')
# 添加标签
ax.bar_label(bars_income, label_type='center', fmt='$%d')
ax.bar_label(bars_expense, label_type='center', fmt='$%d')
ax.set_title('Stacked Bar Chart: Monthly Finance')
ax.set_ylabel('Amount ($)')
ax.legend()
ax.grid(axis='y', alpha=0.3)
plt.show()
categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May']
income = [5000, 5200, 4800, 5500, 6000]
expense = [3000, 3500, 3200, 4000, 4200]
fig, ax = plt.subplots(layout='constrained')
# 第一层柱子(底部)
bars_income = ax.bar(categories, income,
label='Income', color='#2ecc71', edgecolor='white')
# 第二层柱子(堆叠在第一层之上)
bars_expense = ax.bar(categories, expense, bottom=income,
label='Expense', color='#e74c3c', edgecolor='white')
# 添加标签
ax.bar_label(bars_income, label_type='center', fmt='$%d')
ax.bar_label(bars_expense, label_type='center', fmt='$%d')
ax.set_title('Stacked Bar Chart: Monthly Finance')
ax.set_ylabel('Amount ($)')
ax.legend()
ax.grid(axis='y', alpha=0.3)
plt.show()
示例 4:水平柱状图 (barh)
实例
import matplotlib.pyplot as plt
tasks = ['Task A', 'Task B', 'Task C', 'Task D', 'Task E']
hours = [12.5, 8.0, 15.3, 6.2, 10.8]
fig, ax = plt.subplots(figsize=(8, 4), layout='constrained')
# 水平柱状图
bars = ax.barh(tasks, hours,
color='#3498db', edgecolor='white', height=0.6)
# 在柱子末端添加标签
ax.bar_label(bars, fmt='%.1f h', padding=5)
ax.set_title('Task Completion Time (Horizontal Bar)')
ax.set_xlabel('Hours')
ax.invert_yaxis() # 反转 y 轴,使第一个分类在顶部
ax.grid(axis='x', alpha=0.3)
plt.show()
tasks = ['Task A', 'Task B', 'Task C', 'Task D', 'Task E']
hours = [12.5, 8.0, 15.3, 6.2, 10.8]
fig, ax = plt.subplots(figsize=(8, 4), layout='constrained')
# 水平柱状图
bars = ax.barh(tasks, hours,
color='#3498db', edgecolor='white', height=0.6)
# 在柱子末端添加标签
ax.bar_label(bars, fmt='%.1f h', padding=5)
ax.set_title('Task Completion Time (Horizontal Bar)')
ax.set_xlabel('Hours')
ax.invert_yaxis() # 反转 y 轴,使第一个分类在顶部
ax.grid(axis='x', alpha=0.3)
plt.show()
常见问题
bar() 和 barh() 的坐标轴对应关系?
bar(x, height):x 是位置,height 决定柱子高度(垂直方向)。
barh(y, width):y 是位置,width 决定柱子宽度(水平方向)。
注意参数名不同:bar 用 height,barh 用 width 表示数据值。
如何让分组柱状图的柱子紧挨在一起?
将 width 设置为每组柱子总宽度的倒数,并使用 align='edge'。
Matplotlib 参考文档
点我分享笔记