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 轴范围、观察角度、投影方式与盒子比例完善表达。学习时,应重点把握不同数据组织形式与函数选择之间的对应关系。
“点赞有美意,赞赏是鼓励”
热门跟贴