Matplotlib 不仅可以绘制二维图形,也支持基础的三维可视化。在数据分析、科学计算和教学演示中,二维图通常已经能够表达大量信息,但当数据同时涉及三个变量,或者我们希望展示空间轨迹、曲面形状、立体分布时,三维图就具有明显优势。
例如,在二维坐标系中,一条曲线只能表现横轴与纵轴之间的关系;而在三维坐标系中,点、线和面都可以在空间中展开,从而帮助我们观察更复杂的结构。螺旋线、空间点云、函数曲面、立体柱状图等,都是典型的三维可视化对象。Matplotlib 对这些图形提供了基础支持,因此,掌握三维绘图的基本方法,是理解 Matplotlib 图形体系的重要延伸。
一、什么是 Matplotlib 的三维绘图
在二维绘图中,我们主要处理两个坐标轴:横轴 x 与纵轴 y。而在三维绘图中,会进一步引入 z 轴,用来表示第三个方向上的位置或数值变化。这样,数据点就不再只落在一个平面上,而是被放置在三维空间中进行观察。
Matplotlib 的三维绘图主要依赖 mplot3d 工具包。它不是一个与 Matplotlib 完全分离的独立系统,而是在原有绘图框架上的扩展。因此,三维绘图依然延续 Matplotlib 的基本思想:先创建图形对象,再创建坐标轴对象,最后在坐标轴上绘制图形。换句话说,三维绘图并不是一种全新的绘图思路,而是二维绘图在空间维度上的自然扩展。
通常,我们仍然先导入最基础的两个库:
import numpy as np其中:
matplotlib.pyplot 用于创建图形、坐标轴以及控制图形显示;
numpy 用于构造数值数据,尤其适合生成曲线、网格和曲面数据。
二、三维坐标轴是如何创建的
学习 Matplotlib 三维绘图时,首先要理解三维坐标轴的创建方式。因为只有创建出三维坐标轴,后续的散点图、折线图、曲面图等才有意义。
在较早资料中,常见到以下导入方式:
from mpl_toolkits.mplot3d import Axes3D但在当前常用写法中,通常直接通过 projection='3d' 创建三维坐标轴即可。例如:
ax = plt.axes(projection='3d')或者:
ax = fig.add_subplot(111, projection='3d')这两种方式本质上都可以创建三维坐标轴对象。对于初学者来说,第二种写法通常更清楚,因为它明确表明:这个三维坐标轴 ax 属于哪个 Figure 对象。也就是说,三维绘图仍然遵循“图形对象—坐标轴对象”的结构关系,只是这里的坐标轴不再是二维平面,而是三维空间中的绘图区。
三、Matplotlib 三维绘图的基本思路
虽然三维图在视觉上比二维图复杂,但它的绘图流程与二维图并没有本质区别。一般来说,可以概括为以下几个步骤。
1、准备数据
先构造 x、y、z 数据。
如果是三维散点图或三维折线图,通常直接准备三个一维数组即可;
如果是三维曲面图或三维等高线图,则通常需要先构造二维网格数据。
2、创建三维坐标轴
通过 projection='3d' 创建三维坐标轴对象 ax。
3、选择图形类型并绘制
例如:
ax.contour(...):绘制三维等高线图4、补充图形信息
包括:
plt.show():显示图形说明:可根据图形布局需要使用 plt.tight_layout() 或其他布局控制方式。
从结构上看,三维绘图并没有脱离 Matplotlib 的通用模式。真正需要额外注意的,是不同图形对数据组织方式的要求并不完全一样。
四、三维绘图中最常见的图形类型
Matplotlib 支持多种三维图形。最常见、也最值得先掌握的,主要是以下几类。
1、三维散点图
三维散点图使用三个坐标值 (x, y, z) 来唯一确定一个点,因此它适合展示离散点在空间中的分布情况。
ax.scatter(xs, ys, zs)它常用于:
• 观察三维数据的空间分布
• 比较样本在三个变量上的位置
• 展示随机点云或聚类结果
2、三维折线图
三维折线图用于绘制一条在空间中连续变化的轨迹。
ax.plot(xs, ys, zs)与二维折线图相比,它多了一个 z 方向,因此更适合展示:
• 空间轨迹
• 螺旋线、参数曲线
• 某个变量随路径连续变化的过程
3、三维曲面图
三维曲面图用于展示二元函数的整体形状。
ax.plot_surface(X, Y, Z)这里的 X、Y 和 Z 通常都是二维数组,它们共同描述平面上每个网格点的位置和该位置的高度值。因此,曲面图特别适合:
• 数学函数图像
• 地形高度图
• 二维输入、单一输出的函数关系可视化
4、三维柱状图
三维柱状图在三维空间中绘制立体柱体。
ax.bar3d(x, y, z, dx, dy, dz)其中:
x、y、z 表示柱体底部起点;
dx、dy、dz 表示柱体在三个方向上的尺寸。
它适合用于:
• 多组分类数据的立体对比
• 展示“位置 + 高度”型数据
5、三维等高线图
在三维坐标轴对象 ax 上,可使用:
ax.contour(X, Y, Z)绘制三维等高线。它本质上是在 3D 坐标系中展示等值线。
它有时也会配合投影一起使用,以帮助观察曲面高度的层级变化,因此适合:
• 分析曲面的层级结构
• 配合曲面图一起使用,增强对高度变化的理解
五、案例一:3D 散点图
三维散点图是最适合入门的图形之一,因为它的数据组织方式最直接:只要准备三个一维数组,就可以构成一组三维坐标点。
plt.show()
1、np.random.normal(0, 1, 100) 表示生成 100 个服从正态分布的随机数,因此点云大致会集中在原点附近,但会向三维空间中随机散开。
2、三维坐标轴是通过:
ax = fig.add_subplot(111, projection='3d')或者:
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})创建出来的。这说明当前子图是一个三维投影坐标轴,而不是普通二维坐标轴。
3、scatter() 会把 x[i]、y[i]、z[i] 组合成一个空间点,因此 100 个元素会形成 100 个三维散点。
绘制出来的结果通常表现为一团分布在空间中的红色点。它本质上展示的是三组随机变量在三维空间中的联合分布情况。虽然这里的数据是随机生成的,但这种图形在数据探索中很常见。例如,当我们有三个数值特征时,就可以用三维散点图初步观察:
• 点是否集中;
• 是否存在明显的空间分层;
• 是否可能存在离群点。
六、案例二:3D 螺旋线与曲面图
三维绘图不仅可以单独展示一种图形,也可以与子图机制结合起来,形成对比展示。下面这个例子在同一张画布中放置两个三维子图:左侧绘制螺旋线,右侧绘制曲面图。它有助于同时理解“空间轨迹”和“空间曲面”这两种不同的数据表达方式。
plt.show()
1、关于螺旋线图
(1)为什么 x 和 y 会形成圆周运动
在这个例子中:
y1 = np.sin(t)这是参数方程中最经典的一组组合。因为对于任意参数 t,点 (cos(t), sin(t)) 都会落在单位圆上,所以从俯视角度看,这条曲线会绕着原点做圆周运动。
(2)为什么会变成螺旋线
如果只有 x = cos(t) 和 y = sin(t),那么得到的只是二维平面中的圆。现在再加入:
z1 = t这意味着随着参数 t 增大,点在 z 方向不断上升。于是,原本平面中的圆周运动就被“拉伸”为一条向上盘旋的空间曲线,也就是螺旋线。
(3)它适合表达什么
这类图常用于说明:
• 参数曲线
• 周期运动与线性增长的结合
• 三维轨迹的连续变化
2、关于曲面图
(1)为什么曲面图通常要使用网格数据
三维曲面图不是简单地给出三个一维数组,而通常需要一个二维网格。也就是说,要先在平面上生成一系列 x 和 y 的组合点,再计算每个位置对应的函数值 z。例如:
Z2 = np.sin(np.sqrt(X2**2 + Y2**2))这里的 X2 和 Y2 表示平面上的网格点坐标,而 Z2 表示对应位置的高度。只有在这样的网格结构上,plot_surface() 才能把这些点连接成连续的曲面。
(2)这个函数图像有什么特征
函数:
Z = sin(sqrt(X^2 + Y^2))表示高度只与点到原点的距离有关,因此图像通常会呈现一种以原点为中心向外扩散的波纹效果。它很像水面上出现的同心波。
(3)cmap='viridis' 的作用
cmap 用于设置颜色映射方案。曲面图中不同高度会对应不同颜色,因此颜色本身也在帮助表达数值变化。viridis 是 Matplotlib 中较常用的一种渐变配色,层次清晰,适合展示连续数值变化。
(4)edgecolor='none' 的作用
它表示不绘制曲面网格边界线。这样图面会更平滑,更适合观察整体形状。如果保留边界线,图会更强调网格结构,但也可能显得更密、更杂。
七、如何理解三维图的“观看角度”
与二维图相比,三维图还有一个非常重要的问题:同一组数据,从不同角度观察,视觉效果可能差异很大。
例如:
螺旋线从正面看,像一条起伏的曲线;
从上方俯视时,更像一个圆;
曲面图从斜上方看,更容易看出高低起伏;
从正侧面看,则可能只看到局部轮廓。
在实际绘图中,可以通过下列方法调节观察角度:
ax.view_init(elev=30, azim=45, roll=15)其中:
• elev=30:俯视角(elevation),表示观察者相对于水平面的高低角度
• azim=45:方位角(azimuth),表示观察者围绕竖直轴旋转的角度
• roll=15:滚转角,围绕 viewing axis(视线轴)旋转的角度
例如,在前面的螺旋线示例中加上一句:
ax1.view_init(elev=25, azim=45)就可以让读者更容易看出它的盘旋上升结构。
说明:在基础使用中,roll 参数可以省略,此时通常只调整 elev 与 azim。
对于三维图来说,视角并不是纯粹的“美化参数”,而是图形表达的一部分。同一张图,如果视角选择不合适,可能会让空间关系变得难以判断。因此,学习三维绘图时,应有意识地把“选择观察角度”也纳入绘图过程。
八、三维绘图中常见的问题
Matplotlib 的 3D 功能适合教学演示、基础可视化与轻量实验;若需要更复杂的交互式三维场景,往往还需要专门的 3D 可视化工具。
在初学阶段,三维绘图经常会遇到以下几类问题。
1、忘记创建三维坐标轴
如果只是写:
ax = fig.add_subplot(111)那么创建出来的是二维坐标轴,而不是三维坐标轴。此时后续再传入三维数据时,就会报错或表现异常。因此必须加上:
projection='3d'2、曲面图的数据维度不匹配
plot_surface(X, Y, Z) 要求 X、Y、Z 的形状一致,通常都是二维数组。如果直接传入一维数组,往往无法正确绘制曲面。
3、引号格式错误
有些课件或文档中的代码片段可能使用排版引号,如 ‘ ’ 或 “ ”。这些引号在 Python 中不是合法的字符串定界符。编写代码时应统一使用英文半角引号,例如:
ax.scatter(x, y, z, color='red')4、过度依赖三维图
三维图虽然直观,但也更容易因为视角、遮挡和透视效果造成阅读困难。因此在正式分析中,应根据任务选择图形,而不是为了“更立体”就一律改成三维图。很多情况下,二维图反而更清晰。
小结
Matplotlib 的三维绘图建立在二维绘图体系之上,核心在于创建三维坐标轴,并根据数据形状选择合适的绘图方法。入门阶段应重点掌握散点图、折线图、曲面图及视角调整方法,从而建立对三维数据表达方式的基本理解。
“点赞有美意,赞赏是鼓励”
热门跟贴