一、什么是 Matplotlib?
Matplotlib 是 Python 最著名、使用最广泛的二维绘图库,可以创建高质量的静态、动态和交互式可视化图表。
核心特点
- 跨平台:支持 Windows、Linux、macOS
- 多后端:支持 PNG、PDF、SVG 等多种输出格式
- 语法类似 MATLAB:MATLAB 用户容易上手
- 高度可定制:几乎可以控制图形的每个元素
- 丰富图表类型:线图、散点图、柱状图、3D图等
二、安装与导入
安装
pip install matplotlib
导入约定
import matplotlib.pyplot as plt # 主要接口 import numpy as np # 通常与NumPy一起使用
三、基本架构(重要概念)
1. 三层结构
Figure(画布)
↑
Axes(坐标系/子图)← 主要的绘图区域
↑
Axis(坐标轴)2. 核心对象关系
import matplotlib.pyplot as plt # 创建图形和坐标轴 fig, ax = plt.subplots() # 推荐方式(面向对象) # 等价于: # fig = plt.figure() # 创建画布 # ax = fig.add_subplot() # 添加坐标轴 ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # 在坐标轴上绘图 plt.show() # 显示图形
四、两种编程风格
1. MATLAB 风格(简单快速)
import matplotlib.pyplot as plt
# 直接使用 pyplot 函数
plt.figure(figsize=(8, 6)) # 创建图形
plt.plot([1, 2, 3, 4], [1, 4, 2, 3]) # 绘图
plt.title('简单线图') # 添加标题
plt.xlabel('X轴') # X轴标签
plt.ylabel('Y轴') # Y轴标签
plt.grid(True) # 显示网格
plt.show() # 显示图形2. 面向对象风格(推荐,更清晰)
fig, ax = plt.subplots(figsize=(8, 6)) # 创建图形和坐标轴
ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # 在坐标轴上绘图
ax.set_title('简单线图') # 设置标题
ax.set_xlabel('X轴') # 设置X轴标签
ax.set_ylabel('Y轴') # 设置Y轴标签
ax.grid(True) # 显示网格
fig.savefig('plot.png', dpi=300) # 保存图形
plt.show() # 显示图形五、基本图表类型
1. 线图(Line Plot)
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, y,
color='blue', # 颜色
linewidth=2, # 线宽
linestyle='--', # 线型
marker='o', # 标记点
markersize=8, # 标记大小
label='sin(x)') # 图例标签
ax.legend() # 显示图例
plt.show()2. 散点图(Scatter Plot)
np.random.seed(42)
x = np.random.randn(100)
y = np.random.randn(100)
colors = np.random.rand(100)
sizes = 1000 * np.random.rand(100)
fig, ax = plt.subplots(figsize=(10, 6))
scatter = ax.scatter(x, y,
c=colors, # 颜色数组
s=sizes, # 大小数组
alpha=0.5, # 透明度
cmap='viridis')# 颜色映射
ax.set_title('气泡图示例')
fig.colorbar(scatter) # 添加颜色条
plt.show()3. 柱状图(Bar Chart)
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 33]
errors = [2, 3, 4, 1, 2]
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.bar(categories, values,
yerr=errors, # 误差线
color=['red', 'blue', 'green', 'orange', 'purple'],
edgecolor='black',
capsize=5) # 误差线帽子大小
# 添加数值标签
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_ylabel('数值')
ax.set_title('柱状图示例')
plt.show()4. 直方图(Histogram)
data = np.random.randn(1000)
fig, ax = plt.subplots(figsize=(10, 6))
n, bins, patches = ax.hist(data,
bins=30, # 箱数
density=True, # 归一化
alpha=0.7, # 透明度
color='steelblue',
edgecolor='black')
# 添加拟合曲线
from scipy.stats import norm
x = np.linspace(-4, 4, 100)
ax.plot(x, norm.pdf(x), 'r-', linewidth=2)
ax.set_title('正态分布直方图')
ax.set_xlabel('数值')
ax.set_ylabel('频率')
plt.show()5. 饼图(Pie Chart)
labels = ['Python', 'Java', 'C++', 'JavaScript', 'Go']
sizes = [40, 25, 15, 10, 10]
explode = (0.1, 0, 0, 0, 0) # 突出第一块
fig, ax = plt.subplots(figsize=(8, 8))
wedges, texts, autotexts = ax.pie(sizes,
explode=explode,
labels=labels,
autopct='%1.1f%%',
shadow=True,
startangle=90)
# 美化文本
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontsize(12)
ax.set_title('编程语言市场份额')
plt.show()六、多子图布局
1. subplot 网格布局
fig, axes = plt.subplots(2, 3, figsize=(15, 10)) # 2行3列
fig.suptitle('多子图示例', fontsize=16)
# 遍历所有坐标轴
for i, ax in enumerate(axes.flat):
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x + i*0.5)
ax.plot(x, y)
ax.set_title(f'子图 {i+1}')
ax.grid(True)
plt.tight_layout() # 自动调整子图间距
plt.show()2. 复杂布局 GridSpec
fig = plt.figure(figsize=(12, 8))
gs = fig.add_gridspec(3, 3) # 3行3列网格
# 创建不同大小的子图
ax1 = fig.add_subplot(gs[0, :]) # 第一行,全部列
ax2 = fig.add_subplot(gs[1, :2]) # 第二行,前两列
ax3 = fig.add_subplot(gs[1:, 2]) # 第二行到最后,第三列
ax4 = fig.add_subplot(gs[2, 0]) # 第三行,第一列
ax5 = fig.add_subplot(gs[2, 1]) # 第三行,第二列
# 在各个子图中绘图
axes = [ax1, ax2, ax3, ax4, ax5]
for i, ax in enumerate(axes):
ax.plot(np.random.rand(10))
ax.set_title(f'Axes {i+1}')
plt.tight_layout()
plt.show()七、样式与美化
1. 使用内置样式
print(plt.style.available) # 查看所有可用样式
plt.style.use('seaborn-v0_8-darkgrid') # 应用样式
fig, ax = plt.subplots(figsize=(10, 6))
x = np.linspace(0, 10, 100)
for i in range(5):
ax.plot(x, np.sin(x + i*0.5), label=f'曲线 {i+1}')
ax.legend()
plt.show()2. 自定义样式
# 自定义rc参数
plt.rcParams.update({
'figure.figsize': (10, 6), # 图形大小
'font.size': 12, # 字体大小
'axes.titlesize': 16, # 标题大小
'axes.labelsize': 14, # 轴标签大小
'xtick.labelsize': 12, # X轴刻度标签大小
'ytick.labelsize': 12, # Y轴刻度标签大小
'legend.fontsize': 12, # 图例字体大小
'lines.linewidth': 2, # 线宽
'lines.markersize': 8, # 标记大小
})
fig, ax = plt.subplots()
# 绘图...
plt.show()3. 颜色和线型
# 内置颜色缩写
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'w']
# 对应:蓝、绿、红、青、品红、黄、黑、白
# 线型
linestyles = ['-', '--', '-.', ':', 'None']
# 标记点
markers = ['.', ',', 'o', 'v', '^', '<', '>',
'1', '2', '3', '4', 's', 'p', '*',
'h', 'H', '+', 'x', 'D', 'd', '|', '_']
fig, ax = plt.subplots(figsize=(12, 6))
x = np.arange(10)
# 演示不同样式
for i in range(10):
ax.plot(x, x + i,
color=f'C{i}', # 使用调色板颜色
linestyle=linestyles[i % len(linestyles)],
marker=markers[i % len(markers)],
label=f'Line {i+1}')
ax.legend(ncol=2)
plt.show()八、3D 绘图
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10, 8))
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', # 边线颜色
alpha=0.8) # 透明度
# 绘制等高线
ax.contour(X, Y, Z, zdir='z', offset=-1.5, cmap='viridis')
# 设置标签
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
ax.set_title('3D曲面图')
# 添加颜色条
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()九、动画功能
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots(figsize=(8, 6))
x = np.linspace(0, 4*np.pi, 200)
line, = ax.plot(x, np.sin(x))
def update(frame):
line.set_ydata(np.sin(x + frame/10)) # 更新数据
return line,
ani = FuncAnimation(fig, update, frames=100,
interval=50, blit=True)
plt.show()
# 保存动画
# ani.save('animation.gif', writer='pillow', fps=30)十、实战案例
1. 股票数据可视化
# 模拟股票数据
np.random.seed(42)
dates = pd.date_range('2023-01-01', periods=100, freq='D')
prices = 100 + np.cumsum(np.random.randn(100))
fig, axes = plt.subplots(2, 1, figsize=(12, 10))
# 价格走势图
axes[0].plot(dates, prices, 'b-', linewidth=2)
axes[0].fill_between(dates, prices.min(), prices, alpha=0.3)
axes[0].set_title('股票价格走势')
axes[0].set_ylabel('价格')
axes[0].grid(True)
# 收益率直方图
returns = np.diff(prices) / prices[:-1]
axes[1].hist(returns, bins=30, density=True, alpha=0.7)
axes[1].axvline(x=returns.mean(), color='red', linestyle='--', label='均值')
axes[1].set_title('收益率分布')
axes[1].set_xlabel('收益率')
axes[1].set_ylabel('频率')
axes[1].legend()
plt.tight_layout()
plt.show()2. 机器学习结果可视化
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
# 生成数据
X, y = make_classification(n_samples=100, n_features=2,
n_redundant=0, random_state=42)
# 训练模型
model = LogisticRegression()
model.fit(X, y)
fig, ax = plt.subplots(figsize=(10, 8))
# 绘制决策边界
h = 0.02
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制背景
ax.contourf(xx, yy, Z, alpha=0.3, cmap='coolwarm')
# 绘制数据点
scatter = ax.scatter(X[:, 0], X[:, 1], c=y,
cmap='coolwarm', edgecolor='k', s=100)
# 设置图形属性
ax.set_xlabel('特征1')
ax.set_ylabel('特征2')
ax.set_title('逻辑回归决策边界')
plt.colorbar(scatter)
plt.show()实用技巧
1. 保存图形
fig.savefig('figure.png',
dpi=300, # 分辨率
bbox_inches='tight', # 紧凑布局
facecolor='white', # 背景色
edgecolor='none') # 边框2. 显示中文字体
import matplotlib matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体 matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
3. 常用配置
# 创建图形时一次性设置
fig, ax = plt.subplots(figsize=(10, 6),
dpi=100,
facecolor='white',
edgecolor='gray')
# 设置坐标轴范围
ax.set_xlim(0, 10)
ax.set_ylim(-2, 2)
# 设置坐标轴刻度
ax.set_xticks([0, 2, 4, 6, 8, 10])
ax.set_yticks([-2, -1, 0, 1, 2])
# 设置刻度标签
ax.set_xticklabels(['零', '二', '四', '六', '八', '十'])
# 添加文本
ax.text(5, 1.5, '重要数据点',
fontsize=12,
ha='center',
va='center',
bbox=dict(boxstyle='round', facecolor='yellow', alpha=0.5))学习建议
- 从面向对象风格开始:虽然代码稍长,但更清晰、灵活
- 多实践:尝试修改各种参数,观察效果
- 参考官方示例:Matplotlib官网有大量示例和教程
- 结合使用:与Pandas、Seaborn等库配合使用
Matplotlib是Python数据可视化的基石,虽然Seaborn、Plotly等库提供了更高级的接口,但掌握Matplotlib能让你更好地控制图形细节,理解可视化的底层原理。
