Matplotlib 是 Python 中最强大且广泛使用的数据可视化库,支持从基础图表到复杂科学绘图的各类需求。以下是一份结构清晰、内容全面的介绍,涵盖核心概念、功能、代码示例及高级技巧。
前言
安装 Matplotlib
pip install matplotlib
# 或使用 Conda
conda install matplotlib
导入模块
import matplotlib.pyplot as plt
import numpy as np # 通常结合 NumPy 生成数据
1. Matplotlib 核心概念
1.1 对象层次结构
Figure
(画布):整个图表的容器,可包含多个子图(Axes
)。Axes
(子图/坐标系):单个子图的绘制区域,包含坐标轴、标签、标题等。Axis
(坐标轴):控制坐标轴的刻度、标签和范围。Artist
(元素):所有可见元素(如线条、文本、形状)的基类。
1.2 两种绘图接口
pyplot
模块(面向脚本的快捷接口):import matplotlib.pyplot as plt plt.plot(x, y) plt.show()
- 面向对象接口(适合复杂绘图):
fig, ax = plt.subplots() ax.plot(x, y) fig.show()
2. 基础图表类型与代码示例
2.1 折线图(Line Plot)
import numpy as np
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(x, y,
color='red',
linestyle='--',
linewidth=2,
marker='o',
markersize=5,
label='sin(x)')
ax.set_xlabel("X轴", fontsize=12)
ax.set_ylabel("Y轴", fontsize=12)
ax.set_title("正弦函数", fontsize=14)
ax.legend()
ax.grid(True, linestyle=':')
plt.show()
2.2 散点图(Scatter Plot)
x = np.random.randn(100)
y = x + np.random.randn(100) * 0.5
fig, ax = plt.subplots()
sc = ax.scatter(x, y,
c=np.arctan2(y, x), # 颜色映射
s=50, # 点大小
cmap='viridis',
alpha=0.7, # 透明度
edgecolors='black')
fig.colorbar(sc, label='角度值') # 添加颜色条
ax.set_title("带颜色映射的散点图")
plt.show()
2.3 柱状图(Bar Chart)
categories = ['A', 'B', 'C', 'D']
values = [25, 37, 29, 42]
fig, ax = plt.subplots()
bars = ax.bar(categories, values,
color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'],
edgecolor='black',
width=0.6)
# 在柱顶添加数值标签
for bar in bars:
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/2., height,
f'{height}',
ha='center', va='bottom')
ax.set_ylim(0, 50)
ax.set_title("分类柱状图")
plt.show()
2.4 直方图(Histogram)
data = np.random.randn(1000)
fig, ax = plt.subplots()
ax.hist(data,
bins=30,
density=True, # 归一化为概率密度
color='skyblue',
edgecolor='black',
alpha=0.7)
ax.set_title("正态分布数据直方图")
ax.set_xlabel("值")
ax.set_ylabel("频率")
plt.show()
2.5 饼图(Pie Chart)
labels = ['苹果', '香蕉', '橙子', '葡萄']
sizes = [30, 25, 20, 25]
explode = (0.1, 0, 0, 0) # 突出显示"苹果"
fig, ax = plt.subplots()
ax.pie(sizes,
explode=explode,
labels=labels,
autopct='%1.1f%%',
startangle=90,
shadow=True, # 添加阴影
colors=['gold', 'lightcoral', 'lightskyblue', 'lightgreen'])
ax.axis('equal') # 保证饼图为正圆
ax.set_title("水果占比")
plt.show()
3. 高级功能
3.1 多子图布局
fig, axes = plt.subplots(2, 2, figsize=(10, 8)) # 2行2列
# 子图1: 折线图
axes[0, 0].plot(x, np.sin(x), color='green')
axes[0, 0].set_title("子图1")
# 子图2: 散点图
axes[0, 1].scatter(x, y, color='purple')
axes[0, 1].set_title("子图2")
# 子图3: 水平柱状图
axes[1, 0].barh(categories, values, color='orange')
# 子图4: 箱线图
axes[1, 1].boxplot([np.random.randn(100), np.random.randn(100) + 1])
plt.tight_layout() # 自动调整子图间距
plt.show()
3.2 3D 绘图
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
# 生成数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
# 绘制3D曲面
surf = ax.plot_surface(X, Y, Z,
cmap='viridis',
edgecolor='none',
antialiased=True)
fig.colorbar(surf, shrink=0.5, aspect=5)
ax.set_title("3D 曲面图")
plt.show()
3.3 动画
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
x = np.linspace(0, 2*np.pi, 100)
line, = ax.plot(x, np.sin(x))
def animate(frame):
line.set_ydata(np.sin(x + frame/10)) # 更新数据
return line,
ani = FuncAnimation(fig, animate, frames=100, interval=50)
plt.show()
4. 深度定制与优化
4.1 样式配置
- 预定义样式:
plt.style.use('ggplot') # 可选样式:'seaborn', 'dark_background'等
- 自定义全局参数(
rcParams
):plt.rcParams.update({ 'font.size': 12, 'axes.titlesize': 14, 'axes.labelsize': 12, 'xtick.labelsize': 10, 'ytick.labelsize': 10, 'figure.figsize': (8, 6), 'font.family': 'SimHei' # 解决中文显示 })
4.2 复杂元素添加
- 注释与箭头:
ax.annotate('最大值', xy=(np.pi/2, 1), xytext=(np.pi/2 + 1, 0.8), arrowprops=dict(facecolor='black', shrink=0.05))
- 数学公式:
ax.set_title(r'$\frac{\sin(x)}{x}$ 函数') # LaTeX 语法
4.3 坐标轴高级控制
ax.set_xlim(0, 2*np.pi) # 设置范围
ax.set_xticks([0, np.pi, 2*np.pi]) # 自定义刻度
ax.set_xticklabels(['0', 'π', '2π']) # 标签替换
ax.xaxis.set_ticks_position('top') # 刻度位置
ax.yaxis.grid(True, linestyle='--') # Y轴网格
5. 性能优化技巧
- 避免重复绘制:重用
Figure
和Axes
对象。 - 使用
agg
后端(无GUI渲染):import matplotlib matplotlib.use('Agg') # 在导入 pyplot 前设置
- 简化元素:关闭自动缩放(
ax.set_autoscale_on(False)
)、减少刻度数量。 - 大数据优化:对于超过 10^5 数据点,使用
np.histogram
预处理后绘图。
6. 与其他库的集成
6.1 Pandas 集成
import pandas as pd
df = pd.read_csv('data.csv')
df.plot(kind='scatter', x='col1', y='col2', c='col3', cmap='viridis')
plt.show()
6.2 Seaborn 结合
import seaborn as sns
sns.set_theme()
tips = sns.load_dataset("tips")
sns.boxplot(x="day", y="total_bill", data=tips)
plt.title("Seaborn 箱线图")
plt.show()
7. 常见问题解决
- 中文显示乱码:
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # Mac plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
- 保存图片不完整:
plt.savefig('plot.png', bbox_inches='tight', dpi=300)
- 多子图重叠:使用
plt.tight_layout()
或调整subplots_adjust
参数。
8. 扩展库推荐
库名 | 用途 |
---|---|
Seaborn | 统计图表增强 |
Plotly | 交互式网页可视化 |
Bokeh | 动态可视化及大屏展示 |
Cartopy | 地理空间数据可视化 |
Mayavi | 高性能 3D 科学数据可视化 |
9. 学习资源
- 官方文档:Matplotlib Documentation
- 书籍推荐:《Python数据可视化之美》《Matplotlib for Python Developers》
- Cheat Sheet:Matplotlib Cheat Sheet
灵活组合 Matplotlib 的功能,实现从简单的二维图表到复杂的交互式可视化。