条形图(Bar Chart)是展示分类数据最常用的图表,用矩形条的长度表示数值大小。
Matplotlib 提供 bar()(垂直)和 barh()(水平)函数,并支持分组、堆叠和误差线等高级功能。
使用 plt.bar() 绘制垂直条形图,需要传入分类的 x 坐标和对应的高度:
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D']
values = [15, 24, 18, 30]
plt.bar(categories, values)
plt.title('基础垂直条形图')
plt.xlabel('类别')
plt.ylabel('数值')
plt.show()
当类别名称较长时,水平条形图更合适。使用 plt.barh():
categories = ['电子产品', '服装鞋帽', '食品饮料', '家居用品', '美妆个护']
values = [420, 380, 290, 350, 210]
plt.barh(categories, values, color='lightcoral')
plt.title('水平条形图 - 销售额分布')
plt.xlabel('销售额 (万元)')
plt.tight_layout()
plt.show()
barh 的参数顺序不变,但坐标系中 x 轴变为数值轴,y 轴为分类轴。bar() 和 barh() 支持多种样式参数:
| 参数 | 说明 | 示例 |
|---|---|---|
color | 条柱颜色(可统一或序列) | color='skyblue', color=['red','green','blue'] |
edgecolor | 边框颜色 | edgecolor='black' |
linewidth | 边框线宽 | linewidth=1.5 |
width (bar) / height (barh) | 条柱宽度(垂直)或高度(水平),默认0.8 | width=0.5 |
alpha | 透明度 | alpha=0.7 |
categories = ['A', 'B', 'C', 'D']
values = [15, 24, 18, 30]
plt.bar(categories, values, color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'],
edgecolor='black', linewidth=1.5, alpha=0.8)
plt.title('定制颜色与边框')
plt.show()
用于比较多个系列的数据。通过调整条柱的 x 位置实现:
import numpy as np
categories = ['2019', '2020', '2021']
product_a = [20, 34, 45]
product_b = [25, 32, 42]
x = np.arange(len(categories)) # [0,1,2]
width = 0.35 # 条柱宽度
fig, ax = plt.subplots()
bars1 = ax.bar(x - width/2, product_a, width, label='产品 A', color='steelblue')
bars2 = ax.bar(x + width/2, product_b, width, label='产品 B', color='coral')
ax.set_xlabel('年份')
ax.set_ylabel('销量 (万件)')
ax.set_title('分组条形图 - 产品销量对比')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
plt.show()
x - width/2 和 x + width/2 实现并排。使用 bottom 参数(垂直)或 left 参数(水平)将系列堆叠起来:
categories = ['第一季度', '第二季度', '第三季度', '第四季度']
online = [12, 15, 14, 18]
offline = [10, 12, 11, 15]
plt.bar(categories, online, label='线上销售', color='#4CAF50')
plt.bar(categories, offline, bottom=online, label='线下销售', color='#FF9800')
plt.title('堆叠条形图 - 各季度销售额')
plt.ylabel('销售额 (万元)')
plt.legend()
plt.show()
bottom 参数指定第二个系列的起始高度为第一个系列的高度。left 参数,例如 plt.barh(categories, online, label='线上') + plt.barh(categories, offline, left=online, label='线下')。
使用 ax.text() 或 plt.text() 在条柱上添加数值:
categories = ['A', 'B', 'C', 'D']
values = [15, 24, 18, 30]
bars = plt.bar(categories, values, color='skyblue', edgecolor='black')
# 在每个条柱顶部添加数值
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height + 0.5,
f'{height}', ha='center', va='bottom', fontsize=10)
plt.title('带数据标签的条形图')
plt.ylim(0, 35) # 留出标签空间
plt.show()
bars 对象,获取位置和高度。通过 yerr 或 xerr 参数添加误差线,适合展示数据的不确定性:
categories = ['A', 'B', 'C', 'D']
means = [15, 24, 18, 30]
errors = [2, 3, 1.5, 4]
plt.bar(categories, means, yerr=errors, capsize=5, # capsize 控制误差线端帽宽度
color='lightgreen', edgecolor='darkgreen', linewidth=1.5,
error_kw={'elinewidth': 2, 'ecolor': 'red'}) # 误差线样式
plt.title('带误差条的条形图')
plt.show()
import matplotlib.pyplot as plt
import numpy as np
# 数据
years = ['2018', '2019', '2020', '2021']
category1 = [22, 28, 35, 42]
category2 = [18, 25, 32, 38]
category3 = [12, 18, 25, 30]
x = np.arange(len(years))
width = 0.25
fig, ax = plt.subplots(figsize=(10, 6))
bars1 = ax.bar(x - width, category1, width, label='电子产品', color='#1f77b4')
bars2 = ax.bar(x, category2, width, label='服装', color='#ff7f0e')
bars3 = ax.bar(x + width, category3, width, label='家居', color='#2ca02c')
# 添加数据标签
for bars in [bars1, bars2, bars3]:
for bar in bars:
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/2., height + 0.5,
f'{height}', ha='center', va='bottom', fontsize=9)
ax.set_xlabel('年份')
ax.set_ylabel('销售额 (百万)')
ax.set_title('各品类年度销售额对比')
ax.set_xticks(x)
ax.set_xticklabels(years)
ax.legend()
plt.tight_layout()
plt.show()
使用 savefig() 保存为常见格式:
plt.savefig('bar_chart.png', dpi=300, bbox_inches='tight') # PNG 高清
plt.savefig('bar_chart.pdf', bbox_inches='tight') # 矢量图 PDF
条形图是展示分类对比的理想选择。掌握分组、堆叠和标签技巧,能让你的图表更加专业。下一章我们将学习直方图的绘制,用于展示数据分布。