Matplotlib 数据可视化全面教程
Matplotlib 是 Python 生态中最强大、最灵活的数据可视化库之一,由 John D. Hunter 于2003年创建。作为科学计算和数据可视化领域的事实标准,它广泛应用于学术研究、金融分析、商业智能和机器学习等领域。本教程将系统地从基础绘图讲解到高级定制技巧。
1. Matplotlib 基础
1.1 安装与导入
推荐安装方式(推荐使用虚拟环境):
bash
pip install matplotlib numpy pandas # 通常与科学计算库一起安装
基础导入方式:
python
import matplotlib.pyplot as plt # 主要绘图接口
import numpy as np # 数值计算基础库
import pandas as pd # 数据处理常用库
版本检查:
python
print("Matplotlib版本:", plt.__version__)
1.2 创建基本折线图
完整示例代码:
python
# 准备数据
x = [1, 2, 3, 4, 5] # X轴数据
y = [2, 4, 6, 8, 10] # Y轴数据
# 创建画布和绘制图形
plt.figure(figsize=(8, 4)) # 设置图形大小(宽8英寸,高4英寸)
plt.plot(x, y, marker='o', markersize=8) # 绘制带圆点标记的折线
# 添加图表元素
plt.title("简单折线图示例", fontsize=14, fontweight='bold')
plt.xlabel("X轴标签", fontsize=12)
plt.ylabel("Y轴标签", fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7) # 添加虚线网格
# 显示图形
plt.tight_layout() # 自动调整布局
plt.show()
输出效果:
- 显示从(1,2)到(5,10)的直线,每个数据点有圆形标记
- 带有标题、坐标轴标签和灰色虚线网格
- 图形宽高比为2:1
2. 常用图表类型详解
2.1 折线图(Line Plot)
高级应用场景:
- 时间序列数据可视化
- 多组数据对比
- 趋势分析
完整示例:
python
# 生成数据
x = np.linspace(0, 10, 100) # 0到10的100个等间距点
y1 = np.sin(x) # 正弦曲线
y2 = np.cos(x) # 余弦曲线
# 创建图形
plt.figure(figsize=(10, 5))
# 绘制两条曲线
plt.plot(x, y1,
label="sin(x)",
color="red",
linestyle="--",
linewidth=2,
marker='o',
markevery=10) # 每隔10个点显示一个标记
plt.plot(x, y2,
label="cos(x)",
color="blue",
linestyle="-",
linewidth=1.5)
# 添加图表元素
plt.title("三角函数曲线对比", fontsize=14)
plt.xlabel("X值", fontsize=12)
plt.ylabel("函数值", fontsize=12)
plt.legend(fontsize=10, loc='upper right') # 添加图例
plt.grid(True, alpha=0.3) # 半透明网格
# 设置坐标轴范围
plt.xlim(0, 10)
plt.ylim(-1.5, 1.5)
# 自定义刻度
plt.xticks(np.arange(0, 11, 2)) # X轴每2单位一个刻度
plt.yticks(np.arange(-1.5, 1.6, 0.5)) # Y轴每0.5单位一个刻度
plt.tight_layout()
plt.show()
关键参数说明:
参数 | 可选值 | 说明 |
---|---|---|
color |
颜色名称或十六进制值 | 控制线条颜色,如'red'、'#FF0000' |
linestyle |
'-', '--', ':', '-.' | 实线、虚线、点线、点划线 |
linewidth |
数值(默认1.0) | 线条粗细 |
marker |
'o', 's', '^', '*', '+' | 数据点标记样式 |
markersize |
数值 | 标记点大小 |
label |
字符串 | 用于图例显示的标签 |
2.2 散点图(Scatter Plot)
典型应用场景:
- 相关性分析
- 聚类可视化
- 数据分布观察
高级示例:
python
# 生成随机数据
np.random.seed(42) # 确保可重复性
x = np.random.randn(100) # 100个正态分布随机数
y = x + np.random.randn(100) * 0.5 # 添加噪声
sizes = np.abs(np.random.randn(100)) * 100 # 点的大小
colors = np.random.rand(100) # 点的颜色值
categories = np.random.choice(['A', 'B', 'C'], size=100) # 类别数据
# 创建图形
plt.figure(figsize=(9, 6))
# 绘制散点图
scatter = plt.scatter(x, y,
c=colors,
s=sizes,
alpha=0.7, # 半透明
cmap='viridis', # 颜色映射
edgecolors='black', # 边缘色
linewidths=0.5) # 边缘线宽
# 添加颜色条
cbar = plt.colorbar(scatter)
cbar.set_label('颜色值', rotation=270, labelpad=15)
# 添加标题和标签
plt.title("高级散点图示例", fontsize=14)
plt.xlabel("X变量", fontsize=12)
plt.ylabel("Y变量", fontsize=12)
# 添加参考线
plt.axhline(0, color='gray', linestyle='--', linewidth=1)
plt.axvline(0, color='gray', linestyle='--', linewidth=1)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
参数详解:
c
: 颜色值,可以是单一颜色或与数据点对应的值数组s
: 点的大小,单个值或数组alpha
: 透明度(0-1)cmap
: 颜色映射,如'viridis','plasma','coolwarm'等edgecolors
: 点边缘颜色linewidths
: 边缘线宽
2.3 柱状图(Bar Chart)
完整示例:
python
# 准备数据
labels = ['第一季度', '第二季度', '第三季度', '第四季度']
sales_2022 = [120, 150, 180, 210]
sales_2023 = [140, 160, 200, 240]
x = np.arange(len(labels)) # 标签位置
width = 0.35 # 柱状图宽度
# 创建图形
fig, ax = plt.subplots(figsize=(10, 6))
# 绘制柱状图
rects1 = ax.bar(x - width/2, sales_2022, width,
label='2022年', color='skyblue', edgecolor='black')
rects2 = ax.bar(x + width/2, sales_2023, width,
label='2023年', color='salmon', edgecolor='black')
# 添加文本标签
def autolabel(rects):
"""在柱子上方显示数值"""
for rect in rects:
height = rect.get_height()
ax.annotate(f'{height}',
xy=(rect.get_x() + rect.get_width() / 2, height),
xytext=(0, 3), # 3 points vertical offset
textcoords="offset points",
ha='center', va='bottom')
autolabel(rects1)
autolabel(rects2)
# 添加图表元素
ax.set_title('年度销售额对比', fontsize=14)
ax.set_ylabel('销售额(万元)', fontsize=12)
ax.set_xticks(x)
ax.set_xticklabels(labels, fontsize=12)
ax.legend(fontsize=10)
# 添加网格线
ax.yaxis.grid(True, linestyle='--', alpha=0.7)
# 调整Y轴范围
ax.set_ylim(0, 260)
fig.tight_layout()
plt.show()
堆叠柱状图变体:
python
# 准备数据
labels = ['产品A', '产品B', '产品C', '产品D']
online_sales = [20, 35, 30, 35]
offline_sales = [25, 32, 34, 20]
# 创建图形
fig, ax = plt.subplots(figsize=(8, 5))
# 绘制堆叠柱状图
ax.bar(labels, online_sales, label='线上销售', color='tab:blue')
ax.bar(labels, offline_sales, bottom=online_sales,
label='线下销售', color='tab:orange')
# 添加图表元素
ax.set_title('产品销售渠道分布', fontsize=14)
ax.set_ylabel('销售额(万元)', fontsize=12)
ax.legend(fontsize=10)
ax.grid(axis='y', linestyle='--', alpha=0.3)
# 添加数值标签
for i, (online, offline) in enumerate(zip(online_sales, offline_sales)):
ax.text(i, online/2, f'{online}', ha='center', va='center', color='white')
ax.text(i, online + offline/2, f'{offline}', ha='center', va='center', color='white')
plt.tight_layout()
plt.show()
2.4 直方图(Histogram)
高级应用示例:
python
# 生成混合正态分布数据
np.random.seed(42)
data1 = np.random.normal(0, 1, 1000) # 均值0,标准差1
data2 = np.random.normal(5, 1.5, 800) # 均值5,标准差1.5
data = np.concatenate([data1, data2])
# 创建图形
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 绘制基本直方图
ax1.hist(data, bins=30, color='steelblue', edgecolor='white')
ax1.set_title('基本直方图', fontsize=12)
ax1.set_xlabel('数值', fontsize=10)
ax1.set_ylabel('频数', fontsize=10)
ax1.grid(True, alpha=0.3)
# 绘制累积直方图
ax2.hist(data, bins=30, color='salmon', edgecolor='white',
cumulative=True, density=True)
ax2.set_title('累积分布直方图', fontsize=12)
ax2.set_xlabel('数值', fontsize=10)
ax2.set_ylabel('累积比例', fontsize=10)
ax2.grid(True, alpha=0.3)
# 添加整体标题
fig.suptitle('数据分布分析', fontsize=14, y=1.02)
plt.tight_layout()
plt.show()
关键参数:
bins
: 直方图的柱子数量,可以是整数或数组range
: 数据的显示范围,如(0, 10)density
: 是否显示为概率密度cumulative
: 是否显示累积分布histtype
: 'bar'(默认), 'barstacked', 'step', 'stepfilled'
2.5 饼图(Pie Chart)
专业级饼图示例:
python
# 准备数据
sizes = [35, 25, 20, 15, 5]
labels = ['电商', '零售', '批发', '出口', '其他']
explode = (0.05, 0, 0, 0, 0.1) # 突出显示第一和最后一项
colors = ['#ff9999','#66b3ff','#99ff99','#ffcc99','#c2c2f0']
wedgeprops = {'linewidth': 1, 'edgecolor': 'white'} # 饼图边缘样式
# 创建图形
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
# 绘制基本饼图
ax1.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90,
colors=colors, wedgeprops=wedgeprops)
ax1.set_title('基本饼图', fontsize=12)
ax1.axis('equal') # 保证圆形
# 绘制高级饼图
ax2.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
shadow=True, startangle=90, colors=colors,
textprops={'fontsize': 10}, wedgeprops=wedgeprops,
pctdistance=0.85, labeldistance=1.05)
ax2.set_title('带突出效果的饼图', fontsize=12)
ax2.axis('equal')
# 添加中心圆(甜甜圈效果)
centre_circle = plt.Circle((0,0),0.70,fc='white')
ax2.add_artist(centre_circle)
# 添加整体标题
fig.suptitle('销售渠道分布分析', fontsize=14, y=1.02)
plt.tight_layout()
plt.show()
专业技巧:
- 使用
startangle
参数旋转饼图起始角度 - 通过
explode
参数突出重要部分 - 添加
shadow
参数增加立体感 - 使用
wedgeprops
自定义边缘样式 - 添加中心圆创建甜甜圈效果
- 调整
pctdistance
和labeldistance
控制标签位置
3. 多子图布局技巧
3.1 使用plt.subplots()创建复杂布局
网格布局示例:
python
# 创建数据
x = np.linspace(0, 2*np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = np.exp(-x)
# 创建2x2的子图网格
fig, axs = plt.subplots(2, 2, figsize=(12, 8))
# 第一行第一列
axs[0, 0].plot(x, y1, color='tab:blue')
axs[0, 0].set_title('正弦函数', fontsize=12)
axs[0, 0].grid(True, alpha=0.3)
# 第一行第二列
axs[0, 1].plot(x, y2, color='tab:orange')
axs[0, 1].set_title('余弦函数', fontsize=12)
axs[0, 1].grid(True, alpha=0.3)
# 第二行第一列
axs[1, 0].plot(x, y3, color='tab:green')
axs[1, 0].set_title('正切函数', fontsize=12)
axs[1, 0].set_ylim(-5, 5) # 限制Y轴范围
axs[1, 0].grid(True, alpha=0.3)
# 第二行第二列
axs[1, 1].plot(x, y4, color='tab:red')
axs[1, 1].set_title('指数衰减', fontsize=12)
axs[1, 1].grid(True, alpha=0.3)
# 添加整体标题
fig.suptitle('常用数学函数可视化', fontsize=16, y=1.02)
# 调整子图间距
plt.tight_layout()
plt.show()
不规则布局示例:
python
# 创建网格规范
fig = plt.figure(figsize=(12, 6))
gs = fig.add_gridspec(2, 3) # 2行3列网格
# 创建不同大小的子图
ax1 = fig.add_subplot(gs[0, :]) # 第一行全部列
ax2 = fig.add_subplot(gs[1, 0]) # 第二行第一列
ax3 = fig.add_subplot(gs[1, 1:]) # 第二行第二、三列
# 在ax1中绘制
x = np.linspace(0, 10, 100)
ax1.plot(x, np.sin(x), 'r-')
ax1.set_title('主图 - 正弦函数')
# 在ax2中绘制
ax2.hist(np.random.randn(1000), bins=30)
ax2.set_title('直方图')
# 在ax3中绘制
ax3.scatter(np.random.rand(50), np.random.rand(50),
c=np.random.rand(50), s=100*np.random.rand(50))
ax3.set_title('散点图')
plt.tight_layout()
plt.show()
3.2 共享坐标轴的高级用法
共享X/Y轴示例:
python
# 准备数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.exp(-x)
# 创建共享X轴的子图
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(8, 8), sharex=True)
# 绘制各子图
ax1.plot(x, y1, 'b-')
ax1.set_title('正弦函数', fontsize=12)
ax1.grid(True, alpha=0.3)
ax2.plot(x, y2, 'g-')
ax2.set_title('余弦函数', fontsize=12)
ax2.grid(True, alpha=0.3)
ax3.plot(x, y3, 'r-')
ax3.set_title('指数衰减', fontsize=12)
ax3.set_xlabel('X轴', fontsize=10)
ax3.grid(True, alpha=0.3)
# 添加整体标题
fig.suptitle('共享X轴的多子图示例', fontsize=14, y=1.02)
plt.tight_layout()
plt.show()
4. 高级定制技巧
4.1 添加专业注释
完整示例:
python
# 准备数据
x = np.linspace(0, 10, 100)
y = x * np.sin(x)
# 创建图形
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x, y, 'b-', linewidth=2)
# 添加文本注释
ax.text(2, 5, '增长区域', fontsize=12,
bbox=dict(facecolor='white', alpha=0.8, edgecolor='black'))
# 添加箭头注释
ax.annotate('最大值点', xy=(7.85, 7.85), xytext=(4, 8),
arrowprops=dict(facecolor='black', shrink=0.05, width=1, headwidth=8),
bbox=dict(boxstyle="round", fc="w", ec="0.5", alpha=0.9),
fontsize=12)
# 添加水平线和垂直线
ax.axhline(y=0, color='gray', linestyle='--')
ax.axvline(x=7.85, color='red', linestyle=':', alpha=0.5)
# 添加矩形区域
rect = plt.Rectangle((1, -2), 2, 4, color='yellow', alpha=0.3)
ax.add_patch(rect)
# 添加箭头
arrow = plt.Arrow(5, -1, 0, 2, width=0.5, color='green', alpha=0.5)
ax.add_patch(arrow)
# 设置标题和标签
ax.set_title('高级注释示例', fontsize=14)
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
4.2 自定义坐标轴
对数坐标轴示例:
python
# 准备数据
x = np.linspace(1, 100, 100)
y = x ** 2
# 创建图形
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 常规坐标轴
ax1.plot(x, y)
ax1.set_title('线性坐标轴', fontsize=12)
ax1.grid(True, alpha=0.3)
# 对数坐标轴
ax2.plot(x, y)
ax2.set_yscale('log') # Y轴对数坐标
ax2.set_title('对数坐标轴', fontsize=12)
ax2.grid(True, alpha=0.3, which='both') # 主次网格线
# 添加整体标题
fig.suptitle('坐标轴类型对比', fontsize=14, y=1.02)
plt.tight_layout()
plt.show()
双Y轴示例:
python
# 准备数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x) * 100 # 不同量级的数据
# 创建图形和第一个Y轴
fig, ax1 = plt.subplots(figsize=(8, 5))
color = 'tab:red'
ax1.set_xlabel('X轴', fontsize=12)
ax1.set_ylabel('sin(x)', color=color, fontsize=12)
ax1.plot(x, y1, color=color)
ax1.tick_params(axis='y', labelcolor=color)
# 创建第二个Y轴
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('100*cos(x)', color=color, fontsize=12)
ax2.plot(x, y2, color=color)
ax2.tick_params(axis='y', labelcolor=color)
# 添加标题
plt.title('双Y轴示例', fontsize=14, pad=20)
plt.tight_layout()
plt.show()
4.3 样式美化
样式表应用:
python
# 可用样式列表
print(plt.style.available)
"""
['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background',
'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright',
'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid',
'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper',
'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks',
'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']
"""
# 演示不同样式
x = np.linspace(0, 10, 100)
y = np.sin(x)
styles = ['default', 'ggplot', 'seaborn', 'dark_background', 'fivethirtyeight']
fig, axs = plt.subplots(len(styles), 1, figsize=(8, 12))
for i, style in enumerate(styles):
with plt.style.context(style):
axs[i].plot(x, y, label='sin(x)')
axs[i].plot(x, np.cos(x), label='cos(x)')
axs[i].set_title(f'"{style}" 样式', fontsize=12)
axs[i].legend()
axs[i].grid(True)
plt.tight_layout()
plt.show()
自定义样式:
python
# 自定义rc参数
plt.rcParams.update({
'font.size': 12, # 全局字体大小
'axes.titlesize': 14, # 标题字体大小
'axes.labelsize': 12, # 坐标轴标签大小
'xtick.labelsize': 10, # X轴刻度标签大小
'ytick.labelsize': 10, # Y轴刻度标签大小
'legend.fontsize': 10, # 图例字体大小
'figure.titlesize': 16, # 图形标题大小
'grid.color': '0.75', # 网格线颜色
'grid.linestyle': '--', # 网格线样式
'grid.alpha': 0.5, # 网格线透明度
'lines.linewidth': 2, # 线条宽度
'lines.markersize': 8, # 标记大小
'axes.grid': True # 默认显示网格
})
# 使用自定义样式绘图
fig, ax = plt.subplots(figsize=(8, 5))
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.set_title('自定义样式示例', pad=20)
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.legend()
plt.tight_layout()
plt.show()
5. 3D绘图高级技巧
5.1 基本3D绘图
3D曲面图示例:
python
from mpl_toolkits.mplot3d import Axes3D
# 准备数据
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图形
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')
# 绘制3D曲面
surf = ax.plot_surface(X, Y, Z,
cmap='viridis', # 颜色映射
edgecolor='none', # 无边缘线
antialiased=True, # 抗锯齿
rstride=2, # 行步长
cstride=2) # 列步长
# 添加颜色条
fig.colorbar(surf, shrink=0.5, aspect=10, label='Z值')
# 设置标签和标题
ax.set_xlabel('X轴', labelpad=10)
ax.set_ylabel('Y轴', labelpad=10)
ax.set_zlabel('Z轴', labelpad=10)
ax.set_title('3D曲面图', fontsize=14, pad=20)
# 调整视角
ax.view_init(elev=30, azim=45) # 仰角30度,方位角45度
plt.tight_layout()
plt.show()
5.2 3D散点图
高级3D散点图:
python
# 生成随机数据
np.random.seed(42)
n = 500
x = np.random.randn(n)
y = np.random.randn(n)
z = np.random.randn(n)
colors = np.random.rand(n)
sizes = 100 * np.random.rand(n)
# 创建3D图形
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')
# 绘制3D散点
scatter = ax.scatter(x, y, z,
c=colors,
s=sizes,
cmap='plasma',
alpha=0.7,
edgecolors='black',
linewidth=0.5)
# 添加颜色条
cbar = fig.colorbar(scatter, shrink=0.5, aspect=10)
cbar.set_label('颜色值', rotation=270, labelpad=15)
# 设置标签和标题
ax.set_xlabel('X轴', labelpad=10)
ax.set_ylabel('Y轴', labelpad=10)
ax.set_zlabel('Z轴', labelpad=10)
ax.set_title('高级3D散点图', fontsize=14, pad=20)
# 调整视角
ax.view_init(elev=20, azim=35)
plt.tight_layout()
plt.show()
6. 专业输出与保存
6.1 高质量图形保存
保存最佳实践:
python
# 创建示例图形
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, y, 'b-', linewidth=2)
ax.set_title('正弦函数', fontsize=14)
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.grid(True, alpha=0.3)
# 保存为不同格式
fig.savefig('sine_wave.png', # PNG格式
dpi=300, # 高分辨率
bbox_inches='tight', # 紧凑布局
facecolor='white', # 背景色
edgecolor='none') # 无边框
fig.savefig('sine_wave.pdf', # 矢量图PDF
bbox_inches='tight',
transparent=True) # 透明背景
fig.savefig('sine_wave.svg', # 矢量图SVG
bbox_inches='tight')
# 保存为TIFF格式(适合出版)
fig.savefig('sine_wave.tiff',
dpi=300,
bbox_inches='tight',
format='tiff',
compression='lzw') # 无损压缩
print("图形已保存为多种格式")
6.2 多图形批量导出
python
# 创建多个图形
plots = {
'line_plot': plt.figure(figsize=(8, 5)),
'scatter_plot': plt.figure(figsize=(8, 5)),
'bar_chart': plt.figure(figsize=(8, 5))
}
# 填充图形内容
# ...
# 批量保存
import os
output_dir = 'plots'
os.makedirs(output_dir, exist_ok=True)
for name, fig in plots.items():
fig.savefig(f'{output_dir}/{name}.png',
dpi=200,
bbox_inches='tight')
plt.close(fig) # 关闭图形释放内存
print(f"已保存{len(plots)}个图形到{output_dir}目录")
7. 常见问题解决方案
7.1 中文显示问题
完整解决方案:
python
# 方法1:指定中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 方法2:指定具体字体路径(适用于Linux服务器)
import matplotlib.font_manager as fm
font_path = '/usr/share/fonts/truetype/wqy/wqy-microhei.ttc' # 文泉驿微米黑
font_prop = fm.FontProperties(fname=font_path)
# 使用指定字体
plt.title('中文标题示例', fontproperties=font_prop, fontsize=14)
plt.xlabel('X轴标签', fontproperties=font_prop)
plt.ylabel('Y轴标签', fontproperties=font_prop)
# 临时解决方案(不推荐)
plt.title('中文标题'.encode('unicode-escape').decode(), fontsize=14)
7.2 图例位置与样式
高级图例控制:
python
# 准备数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
# 创建图形
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')
ax.plot(x, y3, label='tan(x)')
# 高级图例设置
legend = ax.legend(
loc='upper right', # 位置
frameon=True, # 显示边框
shadow=True, # 阴影效果
fancybox=True, # 圆角边框
framealpha=0.8, # 透明度
edgecolor='black', # 边框颜色
title='函数图例', # 图例标题
title_fontsize=12, # 标题大小
fontsize=10, # 文本大小
ncol=1, # 列数
bbox_to_anchor=(1, 1) # 相对于轴的定位
)
# 调整布局为图例留出空间
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 右侧留出15%空间
plt.show()
7.3 大数显示优化
python
# 准备大数据
x = np.arange(10)
y = np.array([1.5e6, 2.3e6, 3.1e6, 4.2e6, 5.0e6,
6.3e6, 7.1e6, 8.2e6, 9.0e6, 10.5e6])
# 创建图形
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 原始数据显示
ax1.bar(x, y)
ax1.set_title('原始数据显示', fontsize=12)
ax1.set_ylabel('数值', fontsize=10)
ax1.tick_params(axis='x', rotation=45)
# 优化显示格式
ax2.bar(x, y)
ax2.set_title('优化格式显示', fontsize=12)
ax2.set_ylabel('数值(百万)', fontsize=10)
ax2.tick_params(axis='x', rotation=45)
# 使用科学计数法格式化Y轴
from matplotlib.ticker import FuncFormatter
def millions(x, pos):
return f'{x*1e-6:.1f}M'
formatter = FuncFormatter(millions)
ax2.yaxis.set_major_formatter(formatter)
plt.tight_layout()
plt.show()
8. Matplotlib功能速查表
功能类别 | 常用函数 | 关键参数 | 适用场景 |
---|---|---|---|
基础绘图 | plt.plot() |
x, y, linestyle, marker | 折线图、趋势分析 |
plt.scatter() |
x, y, s, c, alpha | 散点图、相关性分析 | |
plt.bar() |
x, height, width, bottom | 柱状图、类别比较 | |
plt.hist() |
x, bins, range, density | 直方图、分布分析 | |
plt.pie() |
sizes, labels, autopct | 饼图、占比分析 | |
子图布局 | plt.subplot() |
nrows, ncols, index | 简单子图布局 |
plt.subplots() |
nrows, ncols, sharex | 推荐子图创建方式 | |
gridspec.GridSpec() |
nrows, ncols, width_ratios | 复杂不规则布局 | |
3D绘图 | Axes3D.plot_surface() |
X, Y, Z, cmap, rstride | 3D曲面图 |
Axes3D.scatter() |
x, y, z, s, c | 3 |