Skip to main content

Matplotlib 数据可视化

Matplotlib 是 Python 最经典的绘图库,其中的 pyplot 模块提供了类似 MATLAB 的绘图接口。几乎所有其他 Python 可视化库都基于它构建。

安装

pip install matplotlib

快速入门

import matplotlib.pyplot as plt

# 最简单的折线图
x = [1, 2, 3, 4, 5]
y = [1, 4, 2, 5, 3]

plt.plot(x, y)
plt.show()

基本元素

一张完整的图通常包含以下元素:

plt.plot(x, y, label='数据 A') # 绘制数据
plt.title('示例图表') # 标题
plt.xlabel('X 轴') # X 轴标签
plt.ylabel('Y 轴') # Y 轴标签
plt.legend() # 图例
plt.grid(True) # 网格线
plt.show()

常用图表类型

折线图

x = range(1, 6)
y1 = [1, 4, 2, 5, 3]
y2 = [2, 3, 5, 2, 4]

plt.plot(x, y1, 'b-o', label='产品 A') # 蓝色、圆点标记、实线
plt.plot(x, y2, 'r--s', label='产品 B') # 红色、方块标记、虚线
# 颜色: b蓝 g绿 r红 c青 m紫 y黄 k黑 w白
# 标记: o圆 s方块 ^三角 *星号
# 线型: -实线 --虚线 -.点划线 :点线
plt.legend()
plt.show()

散点图

import numpy as np

x = np.random.rand(50)
y = np.random.rand(50)
colors = np.random.rand(50)
sizes = 1000 * np.random.rand(50)

plt.scatter(x, y, c=colors, s=sizes, alpha=0.5, cmap='viridis')
plt.colorbar() # 颜色条
plt.show()

柱状图

categories = ['A', 'B', 'C', 'D']
values = [23, 45, 56, 78]

# 垂直柱状图
plt.bar(categories, values, color=['red', 'green', 'blue', 'orange'])
plt.title('分类数据')
plt.show()

# 水平柱状图
plt.barh(categories, values)
plt.show()

# 分组柱状图
x = np.arange(len(categories))
width = 0.35
v1 = [23, 45, 56, 78]
v2 = [30, 40, 60, 70]

plt.bar(x - width/2, v1, width, label='2023')
plt.bar(x + width/2, v2, width, label='2024')
plt.xticks(x, categories)
plt.legend()
plt.show()

直方图

data = np.random.randn(1000) # 1000 个标准正态分布随机数

plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('数据分布')
plt.xlabel('数值')
plt.ylabel('频数')
plt.show()

# 多个直方图叠放
plt.hist(np.random.randn(1000), bins=30, alpha=0.5, label='A')
plt.hist(np.random.randn(1000) + 2, bins=30, alpha=0.5, label='B')
plt.legend()
plt.show()

饼图

sizes = [30, 25, 25, 20]
labels = ['A', 'B', 'C', 'D']
colors = ['gold', 'yellowgreen', 'lightcoral', 'lightskyblue']
explode = (0.1, 0, 0, 0) # 突出显示第一块

plt.pie(sizes, labels=labels, colors=colors, explode=explode,
autopct='%1.1f%%', shadow=True, startangle=90)
plt.title('占比分布')
plt.show()

子图

# 方式一:subplot(基于位置)
plt.subplot(2, 2, 1) # 2×2 网格的第1个位置
plt.plot(x, y1)
plt.title('图1')

plt.subplot(2, 2, 2)
plt.scatter(x, y2)
plt.title('图2')

plt.subplot(2, 2, 3)
plt.bar(categories, values)
plt.title('图3')

plt.subplot(2, 2, 4)
plt.hist(data)
plt.title('图4')

plt.tight_layout() # 自动调整子图间距
plt.show()

# 方式二:subplots(推荐,返回 fig 和 axes)
fig, axes = plt.subplots(2, 2, figsize=(10, 8))

axes[0, 0].plot(x, y1)
axes[0, 0].set_title('图1')

axes[0, 1].scatter(x, y2)
axes[0, 1].set_title('图2')

axes[1, 0].bar(categories, values)
axes[1, 0].set_title('图3')

axes[1, 1].hist(data)
axes[1, 1].set_title('图4')

fig.tight_layout()
plt.show()

样式与保存

# 设置全局样式
plt.style.use('seaborn-v0_8-whitegrid') # 使用内置样式
# 其他可选: 'ggplot', 'bmh', 'dark_background', 'fivethirtyeight'

# 手动设置
plt.rcParams['font.size'] = 12
plt.rcParams['figure.figsize'] = (8, 6)
plt.rcParams['axes.grid'] = True

# 保存图片(在 show 之前)
plt.plot(x, y)
plt.savefig('figure.png', dpi=300, bbox_inches='tight')
plt.savefig('figure.pdf') # 矢量图
plt.show()

中文显示

Matplotlib 默认不支持中文,需要配置字体:

import matplotlib.pyplot as plt

# 方法:直接指定中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题

plt.plot([1, 2, 3], [1, 4, 2])
plt.title('中文标题')
plt.show()

小结

图表函数
折线图plt.plot
散点图plt.scatter
柱状图plt.bar / plt.barh
直方图plt.hist
饼图plt.pie
子图plt.subplots
保存plt.savefig