1. Matplotlib绘图基础与核心概念
Matplotlib是Python生态中最经典的数据可视化库,由John Hunter于2003年创建。作为科学计算领域的事实标准,它提供了类似MATLAB的绘图接口,同时完美支持Numpy数组操作。我在金融数据分析工作中使用Matplotlib已有7年,处理过从简单折线图到复杂3D建模的各种场景。
核心架构分为三层:
- Backend层:处理与操作系统图形界面的底层交互(如Agg、GTK、Qt等)
- Artist层:负责图形元素的绘制和样式控制(Figure、Axes、Line2D等对象)
- Scripting层:面向用户的pyplot模块,提供快速绘图API
安装只需一行命令:
bash复制pip install matplotlib
重要提示:在Jupyter Notebook中使用时,需添加
%matplotlib inline魔法命令才能显示图形。如果是交互式开发,推荐使用%matplotlib notebook获得缩放平移等交互功能。
2. 基础图形绘制实战
2.1 折线图绘制与样式控制
折线图是展示时间序列数据的首选。以下示例展示如何绘制带自定义样式的正弦曲线:
python复制import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
plt.figure(figsize=(10, 5)) # 设置画布尺寸
plt.plot(x, y,
color='#FF6B6B', # 十六进制颜色
linewidth=3, # 线宽
linestyle='--', # 虚线样式
marker='o', # 数据点标记
markersize=8, # 标记尺寸
label='sin(x)') # 图例标签
plt.title("正弦函数曲线", fontsize=14, pad=20) # pad调整标题间距
plt.xlabel("X轴", fontsize=12)
plt.ylabel("Y轴", fontsize=12)
plt.grid(alpha=0.3) # 网格线透明度
plt.legend(loc='upper right') # 图例位置
plt.tight_layout() # 自动调整子图间距
plt.show()
样式控制要点:
- 颜色支持多种格式:颜色名称('red')、十六进制值('#FF6B6B')、RGB元组((1,0,0))
- 线型常用选项:'-'实线、'--'虚线、':'点线、'-.'点划线
- 标记样式:'o'圆形、's'方形、'^'三角形等20余种
2.2 柱状图与分组展示
比较不同类别数据时,柱状图比折线图更直观。下面是分组柱状图的实现方法:
python复制labels = ['2020', '2021', '2022']
sales_A = [23, 45, 37]
sales_B = [34, 30, 41]
x = np.arange(len(labels)) # 生成位置索引
width = 0.35 # 柱宽
fig, ax = plt.subplots(figsize=(8,6))
rects1 = ax.bar(x - width/2, sales_A, width, label='产品A',
color='#4ECDC4', edgecolor='black', linewidth=1)
rects2 = ax.bar(x + width/2, sales_B, width, label='产品B',
color='#FF6B6B', edgecolor='black', linewidth=1)
# 添加数据标签
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), # 垂直偏移
textcoords="offset points",
ha='center', va='bottom')
autolabel(rects1)
autolabel(rects2)
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.set_ylabel('销售额(万元)')
ax.set_title('年度产品销售额对比')
ax.legend()
fig.tight_layout()
分组柱状图技巧:
- 使用
np.arange生成位置索引,通过±width/2实现分组偏移 edgecolor和linewidth参数为柱体添加描边更美观annotate方法添加数据标签时,注意xytext的偏移量单位是points
3. 高级可视化技巧
3.1 多子图与组合图形
使用plt.subplots()可以创建复杂的多子图布局。下面的例子展示2x2网格中包含四种不同类型的图形:
python复制fig, axs = plt.subplots(2, 2, figsize=(12, 10))
# 子图1:散点图
x = np.random.randn(100)
y = x + np.random.randn(100)*0.5
axs[0,0].scatter(x, y, alpha=0.6, c=np.arctan2(y, x), cmap='hsv')
axs[0,0].set_title('彩色散点图')
# 子图2:饼图
sizes = [15, 30, 45, 10]
labels = ['A组', 'B组', 'C组', 'D组']
explode = (0, 0.1, 0, 0) # 突出第二块
axs[0,1].pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
shadow=True, startangle=90)
axs[0,1].axis('equal') # 保证饼图是圆形
axs[0,1].set_title('占比分析')
# 子图3:直方图
mu, sigma = 100, 15
data = mu + sigma * np.random.randn(1000)
axs[1,0].hist(data, bins=30, density=True, alpha=0.6, color='g')
axs[1,0].set_title('正态分布直方图')
# 子图4:箱线图
np.random.seed(10)
data = [np.random.normal(0, std, 100) for std in range(1,4)]
axs[1,1].boxplot(data, vert=True, patch_artist=True,
labels=['组1', '组2', '组3'])
axs[1,1].set_title('分组箱线图')
fig.suptitle('多类型图形组合展示', y=1.02, fontsize=16)
plt.tight_layout()
子图布局经验:
figsize参数应根据子图数量合理设置,避免图形挤压tight_layout()自动调整间距,也可手动指定subplots_adjust参数- 共享坐标轴可通过
sharex/sharey参数实现
3.2 3D图形绘制
Matplotlib支持基本的3D可视化,需要先导入mplot3d工具包:
python复制from mpl_toolkits import mplot3d
fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')
# 生成数据
theta = np.linspace(0, 2*np.pi, 100)
z = np.linspace(0, 10, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
# 绘制3D螺旋线
ax.plot3D(x, y, z, 'blue', linewidth=3, label='螺旋线')
# 添加3D散点
z = np.random.rand(50)*10
x = np.sin(z) + np.random.rand(50)*0.3
y = np.cos(z) + np.random.rand(50)*0.3
ax.scatter3D(x, y, z, c=z, cmap='viridis', s=100, label='散点')
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
ax.set_title('3D图形示例', pad=20)
ax.legend()
# 调整视角
ax.view_init(elev=30, azim=45) # 仰角30度,方位角45度
plt.tight_layout()
3D绘图注意事项:
- 交互式环境中可使用鼠标拖动旋转视角
- 复杂3D场景建议使用Mayavi或Plotly等专业库
view_init参数控制初始视角,elev是仰角,azim是方位角
4. 样式美化与输出控制
4.1 使用样式表快速美化
Matplotlib内置了多种专业设计的样式表,一键切换整体风格:
python复制print(plt.style.available) # 查看可用样式
plt.style.use('seaborn-darkgrid') # 应用样式
x = np.linspace(0, 10, 100)
plt.figure(figsize=(10,5))
for i in range(1,5):
plt.plot(x, np.sin(x + i*0.5)*(10-i),
label=f'曲线{i}',
linewidth=3-i*0.5)
plt.title('不同样式表示例', fontsize=14)
plt.legend()
plt.show()
推荐样式组合技巧:
- 学术论文:
seaborn-poster+LaTeX字体 - 演示报告:
seaborn-darkgrid+ 高对比度颜色 - 网页嵌入:
ggplot+ 离散颜色循环
4.2 输出高质量图片
出版级图片需要调整DPI和输出格式:
python复制fig, ax = plt.subplots(figsize=(8,6))
x = np.random.randn(1000)
ax.hist(x, bins=30, alpha=0.7)
fig.savefig('high_quality.png',
dpi=300, # 打印分辨率
bbox_inches='tight', # 去除白边
facecolor='white', # 背景色
transparent=False, # 是否透明
quality=95) # JPEG质量
输出格式选择指南:
| 格式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| PNG | 网页/印刷 | 无损压缩 | 文件较大 |
| SVG | 矢量图形 | 无限缩放 | 不适用复杂图形 |
| 学术论文 | 矢量质量 | 兼容性问题 | |
| JPEG | 照片类 | 高压缩比 | 有损质量 |
5. 常见问题与性能优化
5.1 中文显示问题解决方案
默认情况下Matplotlib不显示中文,可通过以下方式解决:
python复制# 方法1:使用系统字体(推荐)
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # Mac
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 方法2:指定字体文件路径
import matplotlib.font_manager as fm
font_path = '/path/to/your/font.ttf'
font_prop = fm.FontProperties(fname=font_path)
plt.title('自定义字体标题', fontproperties=font_prop)
5.2 大数据量绘图优化
当数据点超过10万时,可采用以下策略提升性能:
- 降采样显示:
python复制def downsample(data, factor):
return data[::factor]
x = np.linspace(0, 100, 1_000_000) # 100万点
y = np.sin(x) + np.random.randn(1_000_000)*0.1
plt.plot(downsample(x, 100), downsample(y, 100),
alpha=0.5, linewidth=0.5)
- 使用快速渲染方法:
python复制# 改用scatter的优化版本
plt.hexbin(x, y, gridsize=50, cmap='viridis', bins='log')
- 启用加速后端:
python复制import matplotlib
matplotlib.use('Agg') # 非交互式后端
5.3 坐标轴高级控制
精细控制坐标轴能显著提升图表专业性:
python复制fig, ax = plt.subplots(figsize=(10,6))
x = np.linspace(0, 10, 100)
y = np.exp(x)
ax.semilogy(x, y) # Y轴对数坐标
# 设置主要刻度格式
from matplotlib.ticker import ScalarFormatter
ax.yaxis.set_major_formatter(ScalarFormatter())
# 添加次要刻度
ax.yaxis.set_minor_locator(plt.LogLocator(base=10.0, subs=np.arange(2,10)*0.1))
# 自定义刻度标签
def format_fn(tick_val, tick_pos):
if tick_val < 1:
return f"{int(tick_val*100)}%"
return f"${int(tick_val)}$"
ax.xaxis.set_major_formatter(plt.FuncFormatter(format_fn))
ax.grid(which='both', alpha=0.5) # 主次刻度都显示网格
ax.set_title('对数坐标轴高级控制', pad=20)
6. 交互功能与动态可视化
6.1 添加交互控件
使用widgets模块创建交互式控件:
python复制from matplotlib.widgets import Slider, Button
fig, ax = plt.subplots(figsize=(10,6))
plt.subplots_adjust(bottom=0.3) # 为控件留出空间
x = np.linspace(0, 2*np.pi, 1000)
initial_amp = 1.0
line, = ax.plot(x, initial_amp*np.sin(x), lw=2)
ax_amp = plt.axes([0.25, 0.15, 0.65, 0.03])
amp_slider = Slider(
ax=ax_amp,
label='振幅',
valmin=0.1,
valmax=5.0,
valinit=initial_amp,
)
def update(val):
line.set_ydata(amp_slider.val * np.sin(x))
fig.canvas.draw_idle()
amp_slider.on_changed(update)
reset_ax = plt.axes([0.8, 0.025, 0.1, 0.04])
reset_button = Button(reset_ax, '重置', hovercolor='0.975')
def reset(event):
amp_slider.reset()
reset_button.on_clicked(reset)
plt.show()
6.2 动画创建
使用FuncAnimation创建动态可视化:
python复制from matplotlib.animation import FuncAnimation
from IPython.display import HTML
fig, ax = plt.subplots(figsize=(8,6))
x = np.linspace(0, 2*np.pi, 200)
line, = ax.plot(x, np.sin(x), 'r-', linewidth=3)
ax.grid(alpha=0.3)
def animate(i):
line.set_ydata(np.sin(x + i/10.0)) # 相位移动
return line,
ani = FuncAnimation(
fig, animate, frames=100,
interval=50, blit=True)
# 在Jupyter中显示
HTML(ani.to_jshtml())
动画优化技巧:
- 设置
blit=True只重绘变化部分提升性能 interval控制帧间隔(毫秒)- 输出GIF或MP4时需安装ffmpeg
7. 专业图表案例
7.1 热力图与相关性矩阵
python复制import pandas as pd
# 生成模拟数据
data = pd.DataFrame(np.random.randn(100, 5),
columns=['A', 'B', 'C', 'D', 'E'])
corr = data.corr()
fig, ax = plt.subplots(figsize=(8,6))
im = ax.imshow(corr, cmap='coolwarm', vmin=-1, vmax=1)
# 添加颜色条
cbar = ax.figure.colorbar(im, ax=ax, shrink=0.7)
cbar.ax.set_ylabel('相关系数', rotation=-90, va="bottom")
# 设置刻度标签
ax.set_xticks(np.arange(len(corr.columns)))
ax.set_yticks(np.arange(len(corr.columns)))
ax.set_xticklabels(corr.columns)
ax.set_yticklabels(corr.columns)
# 旋转x轴标签
plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
rotation_mode="anchor")
# 添加数值标注
for i in range(len(corr.columns)):
for j in range(len(corr.columns)):
text = ax.text(j, i, f"{corr.iloc[i, j]:.2f}",
ha="center", va="center", color="w")
ax.set_title("变量相关性热力图", pad=20)
fig.tight_layout()
7.2 雷达图绘制
python复制from matplotlib.patches import Circle, RegularPolygon
from matplotlib.path import Path
from matplotlib.projections.polar import PolarAxes
from matplotlib.spines import Spine
def radar_factory(num_vars, frame='circle'):
theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False)
class RadarAxes(PolarAxes):
name = 'radar'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_theta_zero_location('N')
def fill(self, *args, closed=True, **kwargs):
return super().fill(closed=closed, *args, **kwargs)
return theta, RadarAxes
# 示例数据
data = [
['性能指标', '速度', '稳定性', '易用性', '功能', '兼容性'],
['产品A', [90, 70, 85, 80, 75]],
['产品B', [80, 85, 70, 75, 90]]
]
theta, RadarAxes = radar_factory(len(data[0][1:]), frame='polygon')
fig, ax = plt.subplots(figsize=(8,8), subplot_kw=dict(projection='radar'))
ax.set_rgrids([20, 40, 60, 80, 100])
for d in data[1:]:
ax.plot(theta, d[1], label=d[0])
ax.fill(theta, d[1], alpha=0.25)
ax.set_varlabels(data[0][1:])
ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))
plt.title('产品性能雷达图对比', pad=40)
8. 与其他库的集成
8.1 结合Pandas直接绘图
Pandas DataFrame集成了Matplotlib的绘图方法:
python复制import pandas as pd
df = pd.DataFrame({
'年份': [2015, 2016, 2017, 2018, 2019, 2020],
'销售额': [23, 45, 37, 52, 61, 58],
'利润': [5, 7, 8, 9, 12, 11]
})
ax = df.plot(x='年份', y=['销售额', '利润'],
kind='bar',
secondary_y='利润',
figsize=(10,6),
colormap='Paired')
ax.set_ylabel('销售额(万元)')
ax.right_ax.set_ylabel('利润(万元)')
ax.set_title('销售额与利润双轴图')
plt.xticks(rotation=0)
plt.tight_layout()
8.2 在Seaborn中调用Matplotlib
Seaborn是基于Matplotlib的高级封装,可以混合使用:
python复制import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time", height=4)
g.map_dataframe(sns.scatterplot, x="total_bill", y="tip", hue="sex")
g.add_legend()
# 使用Matplotlib方法添加标题
plt.suptitle('不同时段小费分布', y=1.05)
# 调整子图间距
g.fig.subplots_adjust(wspace=0.3, hspace=0.3)
# 单独设置某个子图
g.axes[0,0].set_title('午餐时段')
9. 实用技巧与最佳实践
9.1 图形元素精确定位
使用transforms模块实现元素精确定位:
python复制fig, ax = plt.subplots(figsize=(8,6))
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x), label='sin(x)')
# 在数据坐标(5,0)处添加箭头
ax.annotate('最小值', xy=(4.7, -1), xytext=(3, -0.5),
arrowprops=dict(facecolor='black', shrink=0.05),
bbox=dict(boxstyle="round", fc="w"))
# 使用混合坐标系添加水印
fig.text(0.5, 0.5, '草稿',
fontsize=80, color='gray',
alpha=0.2, ha='center', va='center',
transform=fig.transFigure, rotation=30)
plt.legend()
plt.tight_layout()
9.2 自定义颜色映射
创建非线性颜色映射增强可视化效果:
python复制from matplotlib.colors import LinearSegmentedColormap
# 自定义颜色映射
colors = ["#2E86AB", "#F6F5AE", "#F5F749", "#F24236"]
nodes = [0.0, 0.3, 0.7, 1.0]
cmap_custom = LinearSegmentedColormap.from_list(
"mycmap", list(zip(nodes, colors)))
# 应用示例
x = np.random.randn(1000)
y = np.random.randn(1000)
z = np.sin(x*2) + np.cos(y*2)
plt.figure(figsize=(10,8))
plt.scatter(x, y, c=z, cmap=cmap_custom, s=50, alpha=0.7)
plt.colorbar(label='Z值')
plt.title('自定义颜色映射散点图')
plt.grid(alpha=0.3)
10. 性能监控与调试
10.1 绘图性能分析
使用timeit模块测试不同绘图方法的性能:
python复制import timeit
setup = '''
import numpy as np
import matplotlib.pyplot as plt
x = np.random.rand(100000)
y = np.random.rand(100000)
'''
methods = {
'scatter': 'plt.scatter(x, y, s=1)',
'plot': 'plt.plot(x, y, ",", markersize=1)[0]',
'hexbin': 'plt.hexbin(x, y, gridsize=50, bins="log")'
}
results = {}
for name, code in methods.items():
t = timeit.timeit(stmt=code, setup=setup, number=10)
results[name] = t
plt.figure(figsize=(8,5))
plt.bar(results.keys(), results.values(), color=['#4ECDC4', '#FF6B6B', '#45B7D1'])
plt.ylabel('执行时间(秒)')
plt.title('10万数据点不同绘图方法性能对比')
plt.grid(axis='y', alpha=0.3)
10.2 内存使用优化
处理大型数据集时,可采用以下策略减少内存占用:
- 使用生成器代替数组:
python复制def data_generator(size, chunksize=1000):
for i in range(0, size, chunksize):
yield np.random.randn(chunksize)
fig, ax = plt.subplots()
for chunk in data_generator(1000000, 10000):
ax.plot(chunk, alpha=0.1, color='blue')
- 释放图形内存:
python复制plt.close('all') # 关闭所有图形释放内存
- 使用
lru_cache缓存计算结果:
python复制from functools import lru_cache
@lru_cache(maxsize=32)
def compute_expensive_data(params):
# 复杂计算过程
return processed_data
11. 扩展功能与高级应用
11.1 地理地图绘制
结合cartopy库实现地理可视化:
python复制import cartopy.crs as ccrs
import cartopy.feature as cfeature
fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(1,1,1, projection=ccrs.PlateCarree())
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.COASTLINE, linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linestyle=':')
# 添加城市标记
cities = {
'北京': (116.4, 39.9),
'上海': (121.47, 31.23),
'广州': (113.26, 23.12)
}
for name, (lon, lat) in cities.items():
ax.plot(lon, lat, 'ro', markersize=8, transform=ccrs.PlateCarree())
ax.text(lon+2, lat, name, transform=ccrs.PlateCarree(),
bbox=dict(facecolor='white', alpha=0.7))
ax.set_extent([70, 140, 15, 55]) # 设置显示范围
ax.gridlines(draw_labels=True)
plt.title('中国主要城市分布')
11.2 交互式3D体绘制
使用mplot3d实现体数据可视化:
python复制from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(12,10))
ax = fig.add_subplot(111, projection='3d')
# 生成3D高斯分布数据
x, y, z = np.mgrid[-5:5:30j, -5:5:30j, -5:5:30j]
vol = np.sin(x*y*z)/(x*y*z)
# 提取等值面
verts, faces, _, _ = measure.marching_cubes(vol, 0.1)
# 绘制3D表面
ax.plot_trisurf(verts[:,0], verts[:,1], faces, verts[:,2],
cmap='Spectral', lw=0.1, alpha=0.7)
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
ax.set_title('3D体数据等值面可视化')
plt.tight_layout()
12. 项目实战:股票数据分析仪表盘
综合应用多种技术创建股票分析仪表盘:
python复制import pandas as pd
import pandas_datareader.data as web
from datetime import datetime
# 获取股票数据
start = datetime(2020,1,1)
end = datetime(2023,1,1)
df = web.DataReader('AAPL', 'yahoo', start, end)
# 创建图形
fig = plt.figure(figsize=(16,12), constrained_layout=True)
gs = fig.add_gridspec(3, 2)
# 子图1:价格走势
ax1 = fig.add_subplot(gs[0, :])
df['Close'].plot(ax=ax1, color='#2E86AB', lw=2)
ax1.set_title('AAPL收盘价走势', pad=20)
ax1.grid(alpha=0.3)
# 子图2:成交量
ax2 = fig.add_subplot(gs[1, 0])
df['Volume'].plot(ax=ax2, kind='area', color='#4ECDC4', alpha=0.6)
ax2.set_title('成交量', pad=15)
ax2.grid(alpha=0.3)
# 子图3:收益率分布
ax3 = fig.add_subplot(gs[1, 1])
returns = df['Close'].pct_change().dropna()
ax3.hist(returns, bins=50, color='#FF6B6B', alpha=0.7, density=True)
ax3.set_title('日收益率分布', pad=15)
ax3.grid(alpha=0.3)
# 子图4:移动平均线
ax4 = fig.add_subplot(gs[2, 0])
df['Close'].rolling(20).mean().plot(ax=ax4, label='20日均线', color='#F24236')
df['Close'].rolling(50).mean().plot(ax=ax4, label='50日均线', color='#45B7D1')
ax4.legend()
ax4.set_title('移动平均线', pad=15)
ax4.grid(alpha=0.3)
# 子图5:相关性热图
ax5 = fig.add_subplot(gs[2, 1])
corr = df[['Open', 'High', 'Low', 'Close', 'Volume']].corr()
im = ax5.imshow(corr, cmap='coolwarm', vmin=-1, vmax=1)
fig.colorbar(im, ax=ax5, shrink=0.6)
ax5.set_xticks(range(len(corr.columns)))
ax5.set_yticks(range(len(corr.columns)))
ax5.set_xticklabels(corr.columns, rotation=45)
ax5.set_yticklabels(corr.columns)
ax5.set_title('价格指标相关性', pad=15)
plt.suptitle('AAPL股票分析仪表盘', y=1.02, fontsize=16)
仪表盘开发要点:
- 使用
gridspec实现复杂布局 - 各子图保持统一的视觉风格
- 添加适当的间距和标题层级
- 选择互补色系增强可读性
13. 输出与分享
13.1 创建可交互HTML
使用mpld3库将图形转换为网页交互形式:
python复制import mpld3
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), label=f'曲线{i}')
ax.set_title('可交互图形')
ax.legend()
ax.grid(alpha=0.3)
html_str = mpld3.fig_to_html(fig)
with open("interactive_plot.html", "w") as f:
f.write(html_str)
13.2 嵌入LaTeX文档
配置Matplotlib输出LaTeX兼容的矢量图:
python复制plt.rcParams.update({
"text.usetex": True, # 使用LaTeX渲染文本
"font.family": "serif", # 使用衬线字体
"font.serif": ["Times"], # Times New Roman
"font.size": 11 # 字号
})
fig, ax = plt.subplots(figsize=(6,4))
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x), label=r'$\sin(x)$')
ax.plot(x, np.cos(x), label=r'$\cos(x)$')
ax.set_xlabel(r'$x$轴', fontsize=12)
ax.set_ylabel(r'$y$轴', fontsize=12)
ax.set_title('三角函数曲线', pad=15)
ax.legend()
fig.savefig('latex_figure.pdf',
bbox_inches='tight',
pad_inches=0.05)
14. 版本兼容性与维护
14.1 处理API变更
Matplotlib 3.0+的重要变更及应对方案:
- 默认样式变更:
python复制# 恢复经典样式(兼容旧代码)
plt.style.use('classic')
- 颜色循环调整:
python复制# 显式设置颜色循环
plt.rcParams['axes.prop_cycle'] = plt.cycler(
color=['#1f77b4', '#ff7f0e', '#2ca02c'])
- 3D坐标轴标签:
python复制# 新版本需要单独设置各轴标签
ax.set(xlabel='X', ylabel='Y', zlabel='Z')
14.2 长期维护建议
- 版本锁定:
python复制# requirements.txt中指定版本
matplotlib==3.6.0
- 兼容性检查:
python复制print(f"当前Matplotlib版本: {matplotlib.__version__}")
print(f"Backend: {matplotlib.get_backend()}")
- 弃用警告处理:
python复制import warnings
warnings.filterwarnings('ignore', category=MatplotlibDeprecationWarning)
15. 资源推荐与进阶学习
15.1 官方文档重点
- 画廊示例:https://matplotlib.org/stable/gallery/index.html
- API参考:https://matplotlib.org/stable/api/index.html
- 教程资源:https://matplotlib.org/stable/tutorials/index.html
15.2 推荐扩展库
| 库名称 | 用途 | 特点 |
|---|---|---|
| Seaborn | 统计可视化 | 高级API,美观默认样式 |
| Plotly | 交互式可视化 | 丰富图表类型,Web集成 |
| Bokeh | 交互式仪表盘 | 流数据支持,Web嵌入 |
| Mayavi | 科学计算3D | 大规模数据渲染 |
| HoloViews | 多维数据 | 声明式语法,自动交互 |
15.3 性能优化工具
- Numba加速:
python复制from numba import jit
@jit(nopython=True)
def compute_mandelbrot(width, height, maxiter):
# 高性能计算实现
return result
- Dask并行处理:
python复制import dask.array as da
x = da.random.random((100000, 100000), chunks=(1000, 1000))
y = x.mean(axis=1).compute()
- 内存映射文件:
python复制data = np.memmap('large_array.npy', dtype='float32', mode='r', shape=(10000,10000))