Matplotlib 柱状图:plt.bar() 和 plt.barh() 完全指南
Updated on
柱状图是跨类别比较数量的最常用方式。按季度的收入、按学生的分数、按状态的计数——柱状图使这些比较一目了然。但在 Matplotlib 中创建有效的柱状图需要的不仅仅是简单的 plt.bar() 调用。你需要处理分组比较、堆叠组合、长标签的水平布局,以及使图表自明的适当注释。
本指南涵盖了在 Matplotlib 中你需要的每种柱状图模式,从基本的垂直柱到高级的分组和堆叠配置。
基本垂直柱状图
import matplotlib.pyplot as plt
categories = ['Python', 'JavaScript', 'Java', 'C++', 'Go']
values = [35, 28, 22, 15, 12]
plt.figure(figsize=(8, 5))
plt.bar(categories, values, color='steelblue', edgecolor='black', linewidth=0.5)
plt.xlabel('语言')
plt.ylabel('流行度评分')
plt.title('编程语言流行度')
plt.show()使用 plt.barh() 创建水平柱状图
当类别标签较长或有很多类别时使用水平柱:
import matplotlib.pyplot as plt
frameworks = ['React', 'Vue.js', 'Angular', 'Svelte', 'Next.js',
'Django', 'Flask', 'FastAPI', 'Express', 'Rails']
stars = [220, 207, 95, 78, 124, 78, 67, 74, 64, 55]
plt.figure(figsize=(10, 6))
plt.barh(frameworks, stars, color='#3498db', edgecolor='white')
plt.xlabel('GitHub Stars(千)')
plt.title('按 GitHub Stars 排列的框架流行度')
plt.gca().invert_yaxis() # 最高的在顶部
plt.tight_layout()
plt.show()自定义颜色
import matplotlib.pyplot as plt
categories = ['Q1', 'Q2', 'Q3', 'Q4']
revenue = [120, 150, 180, 200]
# 每个柱不同颜色
colors = ['#e74c3c', '#f39c12', '#2ecc71', '#3498db']
plt.figure(figsize=(8, 5))
bars = plt.bar(categories, revenue, color=colors, edgecolor='black', linewidth=0.5)
plt.ylabel('收入($K)')
plt.title('季度收入')
plt.show()在柱上添加数值标签
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 32]
plt.figure(figsize=(8, 5))
bars = plt.bar(categories, values, color='steelblue')
# 在每个柱顶部添加数值标签
for bar, val in zip(bars, values):
plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 1,
str(val), ha='center', va='bottom', fontsize=11)
plt.ylabel('值')
plt.title('带数值标签的柱状图')
plt.show()分组柱状图
并排比较多个系列:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Q1', 'Q2', 'Q3', 'Q4']
product_a = [20, 35, 30, 35]
product_b = [25, 32, 34, 20]
product_c = [15, 20, 25, 30]
x = np.arange(len(categories))
width = 0.25
plt.figure(figsize=(10, 6))
plt.bar(x - width, product_a, width, label='产品 A', color='#e74c3c')
plt.bar(x, product_b, width, label='产品 B', color='#3498db')
plt.bar(x + width, product_c, width, label='产品 C', color='#2ecc71')
plt.xlabel('季度')
plt.ylabel('销售额($K)')
plt.title('按产品分类的季度销售额')
plt.xticks(x, categories)
plt.legend()
plt.tight_layout()
plt.show()堆叠柱状图
显示每个类别的构成:
import matplotlib.pyplot as plt
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
mobile = [30, 35, 40, 45]
desktop = [50, 45, 35, 30]
tablet = [20, 20, 25, 25]
plt.figure(figsize=(8, 6))
plt.bar(quarters, mobile, label='移动端', color='#3498db')
plt.bar(quarters, desktop, bottom=mobile, label='桌面端', color='#e74c3c')
# 第三层堆叠需要计算累积底部
import numpy as np
bottom_2 = np.array(mobile) + np.array(desktop)
plt.bar(quarters, tablet, bottom=bottom_2, label='平板', color='#2ecc71')
plt.ylabel('流量(%)')
plt.title('按季度的流量来源')
plt.legend()
plt.show()误差线
import matplotlib.pyplot as plt
import numpy as np
categories = ['对照组', '处理 A', '处理 B', '处理 C']
means = [10.2, 15.8, 14.3, 18.1]
errors = [1.2, 2.1, 1.8, 2.5]
plt.figure(figsize=(8, 5))
plt.bar(categories, means, yerr=errors, capsize=5,
color='steelblue', edgecolor='black', linewidth=0.5)
plt.ylabel('响应值')
plt.title('带误差线的处理效果')
plt.show()plt.bar() 参数参考
| 参数 | 类型 | 描述 |
|---|---|---|
x | 类数组 | 柱的位置(类别) |
height | 类数组 | 柱的高度(值) |
width | float | 柱宽(默认 0.8) |
bottom | 类数组 | 柱底部的 Y 坐标(用于堆叠) |
color | 颜色或数组 | 柱的填充颜色 |
edgecolor | 颜色 | 柱的边框颜色 |
linewidth | float | 边框线宽 |
yerr / xerr | 类数组 | 误差线大小 |
capsize | float | 误差线帽宽度 |
align | str | 柱的对齐方式('center' 或 'edge') |
label | str | 图例标签 |
alpha | float | 透明度(0-1) |
使用 PyGWalker 创建交互式柱状图
对于探索性数据分析,PyGWalker (opens in a new tab) 让你在 Jupyter 中通过拖放 DataFrame 的列来创建交互式柱状图:
import pandas as pd
import pygwalker as pyg
df = pd.DataFrame({
'Quarter': ['Q1', 'Q2', 'Q3', 'Q4'] * 3,
'Product': ['A'] * 4 + ['B'] * 4 + ['C'] * 4,
'Sales': [20, 35, 30, 35, 25, 32, 34, 20, 15, 20, 25, 30]
})
walker = pyg.walk(df)FAQ
如何在 Matplotlib 中创建柱状图?
使用 plt.bar(类别, 值) 创建垂直柱或 plt.barh(类别, 值) 创建水平柱。传递类别及其对应值的列表或数组。添加 plt.xlabel()、plt.ylabel() 和 plt.title() 作为标签。
如何创建分组柱状图?
使用 np.arange() 设置 x 位置,每组按柱宽偏移。多次调用 plt.bar() 并使用偏移的 x 位置:plt.bar(x - width, data1, width)、plt.bar(x, data2, width) 等。用 plt.xticks(x, 类别) 设置刻度标签。
如何在柱顶添加数值标签?
遍历柱对象并使用 plt.text()。对每个柱,用 bar.get_x() + bar.get_width() / 2 计算中心 x 位置,用 bar.get_height() 计算 y 位置。使用 ha='center' 进行水平居中。
如何创建堆叠柱状图?
在连续的 plt.bar() 调用中使用 bottom 参数。第一次调用没有 bottom。第二次调用使用第一个数据集作为 bottom。第三层堆叠将前两个数据集求和作为 bottom。
什么时候应该使用水平柱还是垂直柱?
当类别标签较长、类别较多(超过 8-10 个)或与基线比较时使用水平柱(plt.barh())。对于时间序列类别(月、季度)或标签较短的少量类别使用垂直柱(plt.bar())。
总结
Matplotlib 的 plt.bar() 和 plt.barh() 满足了所有柱状图需求:基本比较、分组多系列、堆叠组合和带注释的展示。对于分组柱,使用 np.arange() 偏移 x 位置。对于堆叠柱,使用 bottom 参数。始终添加数值标签以提高清晰度,当标签较长时选择水平布局。