查看全课大纲(第 45 / 51 节)
- 1.Python 是什么?为什么值得学?
- 2.如何为 Python 编程准备一个“全家桶”环境?
- 3.Python 有哪几种执行方法?
- 4.行与缩进到底有什么用?
- 5.注释有什么用,怎么写?
- 6.变量:如何给数据起个好名字?
- 7.运算符的优先级和常见坑点是什么?
- 8.Python 中,数字和布尔值究竟有哪几种?
- 9.输入函数 `input()` 和文件读取 `open()` 怎么用?
- 10.如何将程序的结果展示给用户或保存下来?
- 11.CSV 文件怎么读怎么写才方便?
- 12.列表是什么,如何创建和访问它?
- 13.列表的修改操作,有哪些方法?
- 14.列表切片为什么能取到部分元素?排序和查找又该怎么用?
- 15.判断语句:如何让程序根据条件做不同的事?
- 16.for 循环如何遍历序列中的元素?
- 17.while 循环什么时候才会停?
- 18.while 循环的结束条件,你写对了吗?
- 19.循环中途想提前结束,怎么办?
- 20.`break` 和 `continue` 到底有什么区别?
- 21.列表推导式如何让代码更简洁高效?
- 22.字符串怎么定义、拼接和操作?
- 23.元组:为什么定义单个元素时要加逗号?
- 24.集合(set)怎么用?如何快速去重和做集合运算?
- 25.字典是什么,为什么比列表更方便?
- 26.字典的增删改查与遍历,如何避免 KeyError?
- 27.函数里的变量,为什么有的能用有的不能用?
- 28.在函数内部修改全局变量,为什么有时不生效?
- 29.函数里能修改全局变量吗?返回值怎么用?
- 30.匿名函数:如何用 lambda 快速定义简单函数?
- 31.面向对象编程是什么,为什么需要它?
- 32.类中的方法和属性到底怎么定义和使用?
- 33.如何控制对对象内部属性和方法的访问?
- 34.异常发生时,程序会怎样继续执行?
- 35.如何组织代码:包和模块
- 36.`if __name__ == '__main__'` 到底有什么用?
- 37.如何用 IDE 的 Debug 功能排查程序错误?
- 38.Matplotlib 绘图的第一步该做什么?
- 39.Figure 是什么,如何设置图形尺寸?
- 40.如何自定义 Matplotlib 的坐标轴?
- 41.如何为图表添加图例,让不同曲线一目了然?
- 42.饼图怎么画才能直观展示数据占比?
- 43.如何用 Matplotlib 绘制散点图?
- 44.柱状图怎么画?
- 45.如何使用 Matplotlib 绘制等高线图?
- 46.如何在 Matplotlib 中绘制子图?
- 47.zip 函数如何把多个列表“打包”在一起?
- 48.如何给可迭代对象加上索引?
- 49.random 模块如何生成随机数?
- 50.math 模块怎么用?
- 51.Counter 如何快速统计元素出现次数?
如何使用 Matplotlib 绘制等高线图?
约 10 分钟
小象实战讲义 · Python 编程从入门到实践
在之前的课程中,我们学习了如何使用 Matplotlib 绘制折线图、柱状图等,它们主要描述了两个变量(如 X 和 Y)之间的关系。本节我们将学习一种新的图形——等高线图,它用于可视化三个变量之间的关系:X、Y 以及一个由 X 和 Y 共同决定的函数值 Z。学完本节,你将能够使用 contourf 和 contour 函数绘制出带有颜色填充和边界线的等高线图,并理解其背后的数据准备过程。
💡 核心导读
- 等高线图是什么:一种用于展示三维数据(X, Y, Z)在二维平面上投影的图形,其中 Z 是 X 和 Y 的函数。同一条等高线上的点,其 Z 值相等。
- 核心绘制函数:
plt.contourf用于填充等高线之间的区域,plt.contour用于绘制等高线边界。 - 数据准备关键:绘制前需要使用
np.meshgrid函数将一维的 X、Y 数组转换为二维网格矩阵,这是等高线函数能正确计算的基础。 - 主要参数:
contourf和contour的前三个参数是必需的,分别是网格化的 X、Y 坐标以及 Z 值函数。其他参数如第四个位置参数(层级数量)、alpha(透明度)、cmap(颜色映射)用于控制图形样式。
什么是等高线图?
等高线图是一种将三维曲面投影到二维平面上的可视化方法。想象一座山,地图上用一圈圈的闭合曲线表示相同海拔高度的点,这些曲线就是等高线。
在数学和编程中,我们有一个关于 X 和 Y 的函数 Z = f(X, Y)。等高线图展示的就是所有满足 f(X, Y) = C(C 为某个常数)的 (X, Y) 点的集合。在同一条等高线上,函数值 Z 是相等的。
例如,函数 f(x, y) = x + y 的等高线就是一系列斜率为 -1 的直线,在同一条直线上的所有点,其 x + y 的和都相同。
如何绘制等高线图?
绘制等高线主要用到 Matplotlib 的两个函数:plt.contourf 和 plt.contour。前者用于填充等高线之间的区域(用颜色区分高度),后者用于绘制等高线的边界线。
绘制过程分为三步:
- 准备数据:生成 X 和 Y 的一维坐标数组,并用
np.meshgrid将其转换为二维网格。 - 计算高度:根据函数关系
Z = f(X, Y)计算网格上每个点的高度值。 - 调用绘图函数进行绘制。
下面我们通过一个具体例子来演示,绘制函数 f(x, y) = x² + y² 的等高线图。
import matplotlib
matplotlib.use("Agg") # 无图形界面后端
import matplotlib.pyplot as plt
import numpy as np
# 1. 准备数据:生成一维坐标点
n = 256 # 点的数量,决定图形的精细度
x = np.linspace(-3, 3, n) # 在-3到3之间生成256个等距点
y = np.linspace(-3, 3, n) # Y轴同样范围
# 2. 关键步骤:使用 meshgrid 生成二维网格坐标矩阵
X, Y = np.meshgrid(x, y)
# 现在 X 和 Y 都是二维数组(矩阵),它们共同定义了整个坐标平面上的网格点
# 3. 定义高度函数 Z = f(X, Y)
def height_func(x, y):
return x ** 2 + y ** 2
# 4. 计算网格上每个点的高度值 Z
Z = height_func(X, Y)
# 5. 开始绘图
plt.figure(figsize=(5, 5))
# 使用 contourf 填充颜色区域
# 参数:X, Y网格,Z值,8(将Z值范围分成8个区域进行填充),alpha(透明度),cmap(颜色映射)
plt.contourf(X, Y, Z, 8, alpha=0.75, cmap=plt.cm.hot)
# 使用 contour 绘制等高线边界
# 参数:X, Y网格,Z值,8(绘制8条等高线),colors(边界线颜色)
plt.contour(X, Y, Z, 8, colors='black')
# 释放图形资源,在实际脚本中,如果后续不再绘图,建议调用
plt.close()执行上述代码会生成一个圆形区域的等高线图:黑色的同心圆环就是等高线。因为函数是 x² + y²,所以等高线是标准的圆形。
理解 meshgrid 的作用
为什么不能直接把一维数组 x 和 y 传给 contourf,而必须先用 meshgrid 处理?这是本节的一个关键点。
contourf 和 contour 需要知道平面上每一个点的 (X, Y) 坐标。一维数组 x 和 y 只是分别定义了 X 轴和 Y 轴上的坐标值。meshgrid 的作用就是根据这两个一维数组,生成覆盖整个矩形区域的所有点的坐标矩阵。
简化理解: 假设 x = [1, 2, 3], y = [4, 5]。
X, Y = np.meshgrid(x, y)会生成:X= [[1, 2, 3], [1, 2, 3]] (将 x 在垂直方向复制了 len(y) 次)Y= [[4, 4, 4], [5, 5, 5]] (将 y 在水平方向复制了 len(x) 次)
- 这样,
X和Y中相同位置的元素就配对形成了一个点的坐标。例如,X[0,1]和Y[0,1]是 (2, 4)。
只有这样,我们才能方便地计算每个网格点上的函数值 Z[i, j] = f(X[i, j], Y[i, j])。
调整图形样式:参数详解
contourf 和 contour 函数提供了许多参数来定制图形外观。除了必须的 X, Y, Z,常用的还有:
- 第四个参数(位置参数,层级数量):控制把 Z 值范围分成多少个层级。例如
plt.contourf(X, Y, Z, 8)表示把 Z 值范围分成 8 个区域。 alpha:颜色填充的透明度,范围 0(完全透明)到 1(完全不透明)。cmap:颜色映射(colormap),用于将 Z 值映射到颜色。例如plt.cm.hot(热力图),其他可选值可查阅官方文档。colors:指定等高线的颜色。contour用它控制边界线颜色;contourf也接受这个参数,但填充区域通常交给cmap按高度做颜色渐变。
让我们把填充区域和边界线的数量分别设置,看看效果变化:
import matplotlib
matplotlib.use("Agg") # 无图形界面后端
import matplotlib.pyplot as plt
import numpy as np
# 数据准备
n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)
Z = X ** 2 + Y ** 2
plt.figure(figsize=(5, 5))
# contourf 的第四个参数设为 8:把 Z 值范围分成 8 个区域填充
plt.contourf(X, Y, Z, 8, alpha=0.5, cmap=plt.cm.hot)
# contour 的第四个参数设为 4:只画 4 条边界线
plt.contour(X, Y, Z, 4, colors='blue')
plt.close()这段代码里填充区域是 8 个,边界线只有 4 条:每两个区域之间才出现一条边界线。contourf 和 contour 的第四个参数分别起作用,可以设置成不同的数。
再换一个高度函数,看看等高线的形状有什么变化:
import matplotlib
matplotlib.use("Agg") # 无图形界面后端
import matplotlib.pyplot as plt
import numpy as np
n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)
Z2 = X + Y # 新的高度函数:f(x,y) = x + y
plt.figure(figsize=(5, 5))
plt.contourf(X, Y, Z2, 8, alpha=0.75, cmap=plt.cm.hot)
plt.contour(X, Y, Z2, 8, colors='green')
plt.close()这里绘制函数 Z = X + Y 的等高线:等高线变成了平行的直线,因为对于固定的 Z,方程 X+Y=常数 是一条直线,同一条直线上所有点的 X+Y 值相同。
📝 动手练一练
- 修改函数与观察:把第一个示例的高度函数改成
Z = X + Y,同时把contour的第四个参数从 8 改成 4,运行后观察:填充区域有几个?边界线有几条?
👉 点击查看参考答案
思路:高度函数改成 X + Y 后,等高线会变成平行的直线;contourf 的第四个参数仍然是 8,contour 的参数改成 4,所以填充是 8 个区域、边界线是 4 条。
代码片段:
import matplotlib
matplotlib.use("Agg") # 无图形界面后端
import matplotlib.pyplot as plt
import numpy as np
n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)
Z = X + Y # 修改高度函数
plt.figure(figsize=(5,5))
plt.contourf(X, Y, Z, 8, alpha=.75, cmap=plt.cm.hot)
plt.contour(X, Y, Z, 4, colors='black')
plt.close()观察结果:填充区域有 8 个,边界线只有 4 条,仍然是每两个区域一条边界线;等高线本身是一组平行直线。
常见错误
| 错误写法 | 现象或报错 | 原因 | 正确写法 |
|---|---|---|---|
plt.contourf(x, y, f(x, y), 8)(x, y为一维数组) | TypeError: Input z must be 2D, not 1D。 | contourf 要求 X, Y 是二维网格坐标数组,用于定位平面上每一个点。直接传入一维数组,函数无法构建完整的坐标网格。 | 先用 X, Y = np.meshgrid(x, y) 生成网格,再传入 plt.contourf(X, Y, f(X,Y), 8)。 |
Z = f(x, y)(计算 Z 时仍使用一维 x, y) | 若 x、y 等长,得到一维 Z,后续报 TypeError: Input z must be 2D, not 1D;若 x、y 不等长,则报 ValueError: operands could not be broadcast together with shapes (2,) (3,)。 | 一维的 x 和 y 没有形成网格,无法得到与网格对应的二维 Z 值数组。 | 使用网格化后的 X, Y 计算 Z:Z = f(X, Y)。确保 f 能处理二维数组输入。 |
plt.contourf(X, Y, Z)(省略第四个参数) | 不会报错,但会使用默认的层级数量,层数不受你控制,可能不符合预期。 | 不指定第四个参数时,函数会自动选择默认数量的层级。 | 明确指定层级数量,如 plt.contourf(X, Y, Z, 8)。 |
| 在 Jupyter Notebook 中重复运行绘图代码未关闭图形 | 新的图形会叠加在旧的图形上。 | Matplotlib 默认会将图形绘制到当前“图形”和“坐标轴”上,如果未清除,新的绘图会叠加在旧的之上。 | 在绘图代码开始前使用 plt.figure() 创建新图,或在绘图后使用 plt.close() 关闭并释放图形资源。 |
小结
- 等高线图用于可视化三元函数
Z = f(X, Y),图中同一条曲线上的点具有相同的 Z 值。 - 绘制等高线的两个核心函数是
plt.contourf(填充颜色区域)和plt.contour(绘制边界线),通常配合使用。 - 数据准备是关键:必须先用
np.meshgrid将一维的 X、Y 坐标数组转换为二维网格矩阵(X,Y),再计算对应的二维 Z 值矩阵。 - 主要参数包括:网格数据
X,Y,Z,第四个位置参数(层级数量),填充透明度alpha,颜色映射cmap和边界线颜色colors。 - 通过调整层级数量、
cmap等参数,可以控制图形的精细度和视觉风格,以适应不同的展示需求。
📋 行动清单
- 将示例代码中的高度函数
x**2 + y**2改为x**2 - y**2,运行并观察等高线形状的变化(从圆形变成了双曲线)。 - 尝试在
contourf函数中把cmap从plt.cm.hot换成官方文档里的其他颜色映射,感受颜色对图形表达的影响。 - 查阅 Matplotlib 官方文档中关于
contourf的页面,看看第四个参数还可以怎样指定。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第5章代码包:等高线(含1 个 Notebook)ZIP · 793B