Matplotlib 的三维绘图并不是一套独立系统,而是在原有 Figure、Axes 与子图机制上的扩展。三维图仍沿用标题、坐标轴标签与布局调整等基本框架,只是绘图对象从二维平面延伸到了三维空间。

在较新的 Matplotlib 版本中,只要使用 projection='3d' 创建坐标轴,通常不必再显式导入 Axes3D。但从概念上说,三维坐标轴对象仍然属于 mplot3d 提供的 Axes3D 体系。

注:本文只对三维绘图中独有或特别关键的函数参数进行说明。

一、三维坐标轴创建函数

三维图形的前提是先创建三维坐标轴。

add_subplot(..., projection='3d')

在 Figure 对象中添加一个三维子图,并返回对应的三维 Axes 对象。

ax = fig.add_subplot(nrows, ncols, index, projection='3d')

参数说明:

• projection='3d':指定当前子图为三维投影坐标轴;若省略该参数,则创建的是普通二维子图

返回值:返回一个三维 Axes 对象,通常记作 ax。

示例:

plt.show()

这是一种非常常见、也较清晰的三维坐标轴创建方式。它保留了 Matplotlib 一贯的“先创建图形,再在图形中添加子图”的结构。

axes(projection='3d')

用于创建一个三维坐标区域。

ax = plt.axes(projection='3d')

也可与位置参数一起使用:

ax = plt.axes([left, bottom, width, height], projection='3d')

参数说明:

• projection='3d':指定创建三维坐标轴

返回值:返回一个三维 Axes 对象。

示例:

plt.show()

plt.axes() 在二维绘图中也可以使用,但在三维绘图中,必须明确加上 projection='3d',否则得到的仍然是二维坐标轴。

subplots()

一次性创建 Figure 和一个或多个 Axes 对象。

fig, ax = plt.subplots(nrows=1, ncols=1, figsize=None, subplot_kw={'projection': '3d'})

参数说明:

• subplot_kw:传递给每个子图的关键字参数。在三维绘图中,通常写为 {'projection': '3d'},用于指定创建三维坐标轴

subplots() 的完整接口还包含 sharex、sharey、squeeze、gridspec_kw、**fig_kw 等参数。

返回值:返回一个元组:

• fig:Figure 对象,表示整张画布

• ax 或 axs:子图对象;当创建的是三维子图时,这里得到的是三维坐标轴对象

示例:

plt.show()

subplots() 的优势在于能够一次性完成画布与子图的创建,写法紧凑,特别适合规则的单图或多子图布局。

不过,在三维绘图的教学中,很多示例仍常写成“先 plt.figure(),再 fig.add_subplot(..., projection='3d')”的形式,因为这种写法更容易体现三维坐标轴是如何附加到 Figure 上的。

二、三维基础绘图函数

与二维图形不同,这一组函数需要处理空间中的点、线、面或立体对象。

scatter()

用于绘制三维散点图,展示离散点在三维空间中的分布情况。

ax.scatter(xs, ys, zs=0, zdir='z', s=None, c=None, depthshade=True, **kwargs)

参数说明:

• zs:第三维坐标数据,即各点的 z 值

• zdir:指定第三维所对应的方向,默认是 'z'

• depthshade:是否启用深度阴影效果,用于增强空间层次感

返回值:返回一个 PathCollection 对象。

示例:

plt.show()

与二维散点图相比,三维散点图多了 z 方向,因此每个点由 (x, y, z) 三个值共同确定。

它适合观察三维点云分布、聚类结构或三个变量之间的空间关系。

plot()

用于绘制三维折线图,也可理解为在三维空间中绘制连续轨迹。

ax.plot(xs, ys, zs, **kwargs)

参数说明:

• zs:第三维坐标数据。在 3D 坐标轴中,第三维数据通常作为第三组位置参数传入

返回值:返回一个由线对象组成的列表。

示例:

plt.show()

三维折线图常用于绘制空间轨迹,例如螺旋线、参数曲线或路径变化过程。

从本质上说,它仍然是“按顺序连接数据点”,只是连接发生在三维空间中。

plot_surface()

用于绘制三维曲面图,是三维绘图中最重要的函数之一。它通常用来展示二元函数的整体形状或某个平面区域上的高度变化。

ax.plot_surface(X, Y, Z, *, norm=None, vmin=None, vmax=None, lightsource=None, axlim_clip=False, **kwargs)

参数说明:

• X、Y:网格坐标矩阵

• Z:与 X、Y 对应的高度矩阵

• rcount:行方向参与绘制的最大采样数,默认 50

• ccount:列方向参与绘制的最大采样数,默认 50

• cmap:颜色映射方案,用于根据高度显示不同颜色

rainbow:彩虹渐变,视觉鲜艳,但不太适合严肃的数据表达

• edgecolor:曲面网格边界颜色

其它合法颜色名:如 'red'、'blue'、'green' 等

• rstride:行方向采样步长

• cstride:列方向采样步长

• linewidth:网格线宽

• antialiased:是否启用抗锯齿

• alpha:透明度

返回值:返回一个 Poly3DCollection 对象。

示例:

plt.show()

plot_surface() 与散点图、折线图不同,它要求输入数据通常是二维网格结构。因此,在使用前往往需要先通过 np.meshgrid() 构造 X、Y 网格,再计算对应的 Z 值。

plot_surface() 默认会通过 rcount 和 ccount 控制每个方向参与绘制的最大采样数,默认均为 50;也可以改用 rstride、cstride 指定步长。对于网格非常密集的数据,这一机制有助于控制绘图开销。

plot_wireframe()

用于绘制三维线框图。

ax.plot_wireframe(X, Y, Z, **kwargs)

参数说明:

• X、Y、Z:二维数组,表示曲面上各点的坐标

• rcount、ccount:每个方向上用于绘制的最大采样数,默认均为 50

• rstride、cstride:行和列的步长,可用于控制线框稀疏程度

• color:线框颜色

• linewidth:线宽

• axlim_clip:是否裁剪坐标轴范围外的线框,默认 False。

返回值:返回一个 Line3DCollection 对象。

示例:

plt.show()

plot_wireframe() 与 plot_surface() 类似,都用于展示曲面形状;不同的是,线框图更强调网格结构本身,适合观察曲面的整体轮廓与起伏变化。官方文档还说明,若输入数据点过多,函数会按 rcount 和 ccount 自动下采样。

plot_trisurf()

用于绘制基于三角剖分的三维曲面图。

ax.plot_trisurf(*args, color=None, **kwargs)

参数说明:

plot_trisurf() 的参数形式比 plot_surface() 更灵活,常见写法有两类:

第一类,直接传入三角剖分对象:

ax.plot_trisurf(triangulation, Z, ...)

第二类,直接传入点坐标:

ax.plot_trisurf(X, Y, Z, ...)

常用参数包括:

• X、Y、Z:曲面点坐标

• triangles:三角形顶点索引

• cmap:颜色映射方案

• color:整体颜色

• linewidth:边界线宽

• antialiased:是否抗锯齿

• axlim_clip:是否裁剪坐标轴范围外的内容。

返回值:返回一个 Poly3DCollection 对象。

示例:

plt.show()

plot_surface() 通常要求输入规则网格数据,因此常常需要先用 np.meshgrid() 构造二维网格;而 plot_trisurf() 不要求点必须落在规则网格上,它会根据平面散点自动进行三角剖分,再生成曲面。正因为如此,它更适合处理实验采样点、地形离散点、传感器测量点等不规则空间数据。

bar3d()

用于绘制三维柱状图,在三维空间中显示立体柱体。

ax.bar3d(x, y, z, dx, dy, dz, color=None, zsort='average', shade=True, **kwargs)

参数说明:

• x:柱体底部起点的 x 坐标

• y:柱体底部起点的 y 坐标

• z:柱体底部起点的 z 坐标

• dx:柱体在 x 方向上的宽度

• dy:柱体在 y 方向上的宽度

• dz:柱体在 z 方向上的高度

• zsort:柱体排序方式,影响渲染顺序

'max':按柱体相关顶点 z 值的最大值决定绘制顺序

• shade:是否启用阴影效果

返回值:返回一个 Poly3DCollection 对象。

示例:

plt.show()

三维柱状图可以看作二维柱状图在空间中的扩展。

不过,由于三维图存在遮挡与透视问题,它虽然更立体,却不一定总比二维柱状图更清晰。因此在正式分析中应根据任务选择。

contour()

用于绘制三维等高线图,展示曲面的等值线结构。

ax.contour(X, Y, Z, levels=None, zdir='z', offset=None, cmap=None, **kwargs)

参数说明:

• X:网格点的 x 坐标二维数组

• Y:网格点的 y 坐标二维数组

• Z:对应位置的高度值二维数组

• levels:等高线层级数量或具体层级值

• zdir:指定等高线投影方向

• offset:投影偏移位置

• cmap:颜色映射方案

返回值:返回一个 QuadContourSet 对象。

示例:

plt.show()

这里的 ax.contour() 是在三维坐标轴上绘制等高线,可直接显示在三维空间中,也可结合 zdir 与 offset 做投影。

三维等高线图常用于辅助观察曲面的层级变化。它既可以单独绘制,也可以与 plot_surface() 配合使用,使曲面的高低结构更加清晰。

contourf()

用于绘制三维填充等高线图。

ax.contourf(X, Y, Z, *args, zdir='z', offset=None, **kwargs)

参数说明:

• *args:等高线层级等额外参数

• zdir:等高线延伸或投影的方向,可取 'x'、'y'、'z'

• offset:若指定,则将填充等高线投影到与 zdir 垂直的平面上

• cmap:颜色映射方案

• axlim_clip:是否裁剪坐标轴范围外的内容,默认 False

返回值:返回一个 QuadContourSet 对象。

示例:

plt.show()

contourf() 可以看作 contour() 的填充版本。它不仅能显示等值分层,还能通过颜色填充增强层次感;若配合 offset 使用,还可以把填充等高线投影到某个坐标平面上。

quiver()

用于绘制三维箭头场。

ax.quiver(X, Y, Z, U, V, W, **kwargs)

参数说明:

• X、Y、Z:箭头起点坐标

• U、V、W:箭头在三个方向上的分量

• length:箭头长度缩放因子,默认 1

• arrow_length_ratio:箭头头部相对于整体长度的比例,默认 0.3

• pivot:箭头锚点位置,可取 'tail'、'middle'、'tip'

• normalize:是否将箭头长度归一化,默认 False

• axlim_clip:是否裁剪坐标轴范围外的箭头,默认 False

返回值:返回一个 Line3DCollection 对象。

示例:

plt.show()

quiver() 常用于展示方向、速度、力场、梯度等向量信息。与散点图展示“位置”不同,箭头图同时表达了“位置 + 方向 + 大小”三类信息。

三、三维图形修饰函数

三维图除了常见的标题、横轴标签、纵轴标签之外,还多了 z 轴和观察角度等三维特有信息。因此,这一组函数在三维图中尤其重要。

set_title()

用于设置三维子图标题。

ax.set_title(label, fontdict=None, loc=None, pad=None, **kwargs)

参数说明:

该函数与二维绘图中的 set_title() 用法相同,三维绘图中没有新增的独有参数。

返回值:返回一个 Text 对象。

示例:

ax.set_title("三维曲面图")

该函数虽然不是三维绘图独有,但在三维图中同样用于说明图形内容,常与 set_xlabel()、set_ylabel()、set_zlabel() 配合使用。

set_xlabel()/set_ylabel()

用于设置三维坐标轴中的 x 轴与 y 轴标签。

ax.set_ylabel(ylabel, fontdict=None, labelpad=None, **kwargs)

参数说明:

与二维绘图中的同名函数一致,三维场景中没有额外独有参数。

返回值:返回一个 Text 对象。

示例:

ax.set_ylabel("Y")

set_zlabel()

用于设置三维坐标轴的 z 轴标签。

ax.set_zlabel(zlabel, fontdict=None, labelpad=None, **kwargs)

参数说明:

• zlabel:z 轴标签文本

• 其余参数含义与 set_xlabel()、set_ylabel() 类似

返回值:返回一个 Text 对象。

示例:

plt.show()

set_zlim()

用于设置三维坐标轴 z 轴的显示范围。

ax.set_zlim(bottom=None, top=None)

参数说明:

• bottom:z 轴下界

• top:z 轴上界

返回值:返回设置后的 z 轴范围。

示例:

ax.set_zlim(0, 20)

当 z 方向数据跨度较大,或者希望突出某一高度区间时,set_zlim() 很有用。它与二维图中的 set_xlim()、set_ylim() 在作用逻辑上是一致的。

view_init()

用于设置三维图的观察角度。它决定读者从什么方向观看当前三维图形,因此在三维绘图中非常重要。

ax.view_init(elev=None, azim=None, roll=None, vertical_axis='z', share=False)

参数说明:

• elev:仰角,即从竖直方向上观察的角度

• azim:方位角,即绕垂直轴旋转的角度

• roll:绕观察方向的旋转角度

• vertical_axis:指定哪个轴视为竖直方向,默认是 'z'

返回值:无返回值,主要起视角设置作用。

示例:

plt.show()

三维图的可读性在很大程度上依赖视角。

同一组数据,如果观察角度不合适,空间结构可能会变得难以辨认。因此,view_init() 不是单纯的美化函数,而是三维表达的重要组成部分。

set_proj_type()

用于设置三维图的投影方式。它决定三维场景是采用透视投影还是正交投影,从而影响图形的空间视觉效果。

ax.set_proj_type(proj_type, focal_length=None)

参数说明:

• proj_type:投影类型,常见取值为:

'ortho':正交投影,不表现近大远小,更适合强调几何结构与尺寸关系

• focal_length:焦距参数,主要用于透视投影效果调节

返回值:无返回值。

示例:

plt.show()

view_init() 解决的是“从哪个方向看”,而 set_proj_type() 解决的是“用什么投影方式看”。二者共同决定三维图的视觉呈现。官方专门提供了 3D plot projection types 示例来展示不同投影方式的效果差异。

set_box_aspect()

用于设置三维坐标轴盒子的显示比例。

ax.set_box_aspect(aspect, *, zoom=1)

参数说明:

• aspect:三维坐标轴盒子的比例,通常写成三元组,如 (1, 1, 1) 或 (2, 1, 1)

• zoom:缩放系数,默认 1

返回值:无返回值。

示例:

plt.show()

set_box_aspect() 控制的是三维坐标轴外框在显示中的比例,而不是数据本身的数值比例。官方文档指出,其默认盒子比例为 4:4:3。在三维图中,如果默认显示效果让图形显得“过扁”或“过高”,这个函数非常有用。

tight_layout()

自动调整子图间距,减少多子图场景中的标题、标签和刻度重叠。

plt.tight_layout(pad=1.08)

或:

fig.tight_layout(pad=1.08)

参数说明:

与二维绘图中的 tight_layout() 基本一致,三维绘图中没有新增独有参数。

返回值:无显式返回值。

示例:

plt.tight_layout()

tight_layout() 可用于对子图间距做基础性的自动调整,但官方文档同时指出,它属于较早的布局机制,只检查刻度标签、轴标签和标题等元素的范围。在复杂三维多子图场景中,它的效果可能有限;若布局更复杂,通常更推荐使用 constrained_layout。

小结

Matplotlib 三维绘图的关键,是先创建三维坐标轴,再根据数据特点选择点、线、曲面、柱体或向量场等函数,最后结合 z 轴范围、观察角度、投影方式与盒子比例完善表达。学习时,应重点把握不同数据组织形式与函数选择之间的对应关系。

点赞有美意,赞赏是鼓励