数据可视化——matplotlib库
Matplotlib 数据可视化全面教程
Matplotlib 是 Python 生态中最强大、最灵活的数据可视化库之一,由 John D. Hunter 于2003年创建。作为科学计算和数据可视化领域的事实标准,它广泛应用于学术研究、金融分析、商业智能和机器学习等领域。本教程将系统地从基础绘图讲解到高级定制技巧。
1. Matplotlib 基础
1.1 安装与导入
推荐安装方式(推荐使用虚拟环境):
pip install matplotlib numpy pandas # 通常与科学计算库一起安装
基础导入方式:
import matplotlib.pyplot as plt # 主要绘图接口
import numpy as np # 数值计算基础库
import pandas as pd # 数据处理常用库
版本检查:
print("Matplotlib版本:", plt.__version__)
1.2 创建基本折线图
完整示例代码:
# 准备数据
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)
高级应用场景:
- 时间序列数据可视化
- 多组数据对比
- 趋势分析
完整示例:
# 生成数据
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)
典型应用场景:
- 相关性分析
- 聚类可视化
- 数据分布观察
高级示例:
# 生成随机数据
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)
完整示例:
# 准备数据
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 offsettextcoords="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()
堆叠柱状图变体:
# 准备数据
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)
高级应用示例:
# 生成混合正态分布数据
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)
专业级饼图示例:
# 准备数据
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()创建复杂布局
网格布局示例:
# 创建数据
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()
不规则布局示例:
# 创建网格规范
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轴示例:
# 准备数据
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 添加专业注释
完整示例:
# 准备数据
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 自定义坐标轴
对数坐标轴示例:
# 准备数据
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轴示例:
# 准备数据
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 样式美化
样式表应用:
# 可用样式列表
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()
自定义样式:
# 自定义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曲面图示例:
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散点图:
# 生成随机数据
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 高质量图形保存
保存最佳实践:
# 创建示例图形
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', # 矢量图PDFbbox_inches='tight',transparent=True) # 透明背景fig.savefig('sine_wave.svg', # 矢量图SVGbbox_inches='tight')# 保存为TIFF格式(适合出版)
fig.savefig('sine_wave.tiff', dpi=300, bbox_inches='tight',format='tiff',compression='lzw') # 无损压缩print("图形已保存为多种格式")
6.2 多图形批量导出
# 创建多个图形
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 中文显示问题
完整解决方案:
# 方法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 图例位置与样式
高级图例控制:
# 准备数据
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 大数显示优化
# 准备大数据
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 |