如何用Matplotlib绘制带下坡方向刻度的-x³/3+xy²+x函数等高线图?
在Matplotlib中绘制带下坡方向刻度的等高线图
要实现目标,核心是利用函数梯度的反方向即为下坡方向这一原理,结合Matplotlib的等高线绘制工具和箭头标注完成。以下是具体实现步骤和代码:
1. 导入依赖库
import numpy as np import matplotlib.pyplot as plt
2. 定义目标曲面函数
def f(x, y): return -x**3 / 3 + x * y**2 + x
3. 生成网格数据与函数值
创建x、y的网格,并计算每个网格点对应的函数值:
# 定义x、y的取值范围和精度 x = np.linspace(-2, 2, 100) y = np.linspace(-2, 2, 100) X, Y = np.meshgrid(x, y) Z = f(X, Y)
4. 计算下坡方向向量
通过numpy.gradient计算函数的梯度(上坡方向),取反后得到下坡方向,并对方向向量归一化,保证箭头大小一致:
# 计算梯度(dx: 沿x轴的变化率,dy: 沿y轴的变化率) dz_dx, dz_dy = np.gradient(Z) # 下坡方向为梯度的反方向,归一化向量 norm = np.sqrt(dz_dx**2 + dz_dy**2) # 避免除以0的情况 norm[norm == 0] = 1 dx_down = -dz_dx / norm dy_down = -dz_dy / norm
5. 绘制等高线与下坡方向箭头
先绘制基础等高线,再遍历每条等高线的路径,在等高线上标注指向下坡的箭头,同时添加数值标签:
fig, ax = plt.subplots(figsize=(8, 6)) # 绘制等高线,设置合适的层级数量 contour = ax.contour(X, Y, Z, levels=15, cmap='viridis') # 添加等高线数值标签 ax.clabel(contour, inline=True, fontsize=10, fmt='%.1f') # 在等高线上绘制下坡方向箭头 arrow_step = 10 # 控制箭头的密度,值越大箭头越少 for collection in contour.collections: for path in collection.get_paths(): verts = path.vertices # 获取等高线路径上的所有点 for i in range(0, len(verts) - arrow_step, arrow_step): x_p, y_p = verts[i] # 找到该点在网格中的近似索引 x_idx = np.argmin(np.abs(x - x_p)) y_idx = np.argmin(np.abs(y - y_p)) # 获取该点的下坡方向向量 dir_x = dx_down[y_idx, x_idx] dir_y = dy_down[y_idx, x_idx] # 绘制箭头(调整head_width和length控制箭头大小) ax.arrow(x_p, y_p, dir_x * 0.12, dir_y * 0.12, head_width=0.06, head_length=0.06, fc='red', ec='red', zorder=5) # 设置图表标签与标题 ax.set_xlabel('x') ax.set_ylabel('y') ax.set_title('曲面 $-x^3/3 + xy^2 + x$ 的等高线图(箭头指向下坡方向)') plt.tight_layout() plt.show()
关键说明
- 梯度的反方向:函数的梯度指向数值增大的上坡方向,取反后就是数值减小的下坡方向。
- 箭头密度:通过
arrow_step参数控制等高线上箭头的数量,根据需求调整即可。 - 箭头样式:可以修改
arrow函数的head_width、head_length、颜色等参数,匹配你的参考图样式。
内容的提问来源于stack exchange,提问作者random0620
相关产品推荐
相关产品推荐

