本节摘要:三维绘图家族面向二维自变量的函数数据,核心成员是
plot3、surf、mesh、contour与视角控制view。本节以一个二元函数为主线,讲网格生成、曲面着色、等高线投影与相机视角,并给出三维图的可读性守则。
二维图回答"y 随 x 怎么变",三维图回答"z 随 x、y 怎么变"。场的数据形态——温度场、高度场、势能面——在工程分析里到处都是,mesh 与 surf 就是为它们准备的。八十年代末到九十年代,配合句柄图形的引入,这套三维能力让 Matlab 在工程可视化上站稳了位置。
[X, Y] = meshgrid(-3:0.2:3, -3:0.2:3); Z = peaks(X, Y); % 经典双峰测试函数 surf(X, Y, Z); % 曲面 xlabel('X'); ylabel('Y'); zlabel('Z');
meshgrid 把两个一维坐标撑成网格矩阵,这是三维绘图的第一步、也是最容易被漏掉的一步——surf 需要的是网格,不是散点。三个函数的分工:surf 实面着色,适合展示场的连续形态;mesh 只画网格线,数据量大时更快也更透气;contour 把高度压成等高线,回到二维平面,可读性往往最高。实践中我喜欢 surf 加底面投影的组合:
surfc(X, Y, Z); % 曲面 + 底部等高线投影,一步到位 shading interp; % 平滑着色,去掉格面之间的接缝
更直接的做法是 surfc(X, Y, Z)——曲面加底部等高线一步到位。着色方式用 shading 控制:shading interp 平滑插值,shading faceted 保留网格。
view(45, 30); % 方位角45度、仰角30度 axis tight; colorbar; % 收紧框距、给高度配标尺
视角就是三维图的光圈。默认视角经常把关键结构挡在背面,view 两个角度反复调,直到主结构不被遮挡。更精细的控制交给相机函数(camzoom、camorbit),交互式调整可以直接用工具栏的旋转按钮拖拽,满意后用 campos/view 把角度固化进代码。
切片观察体数据(三维自变量加一维函数值)时:
slice(X, Y, Z, V, xq, yq, zq) % 在指定平面上切出函数值分布

三维图最大的敌人是"好看但读不出数"。守则三条:等高线优先——若结论能写在等高线上,就不需要立体;必须立体时配 colorbar 标明高度含义;导出前转一转视角,确认没有结构被永久挡住。论文里大量出现的"装饰性三维"其实都是二维就能讲清的内容,这是值得克制的诱惑。
💡 关键直觉:
meshgrid生成的是"格点",surf画的是"格面"。点阵与面阵的差一个1(行数差一),这解释了为什么散点数据要先griddata插值成规则网格才能画曲面。
主线扩展:手头只有激光测高的散点数据(不规则位置的三维坐标),目标是可放进报告的曲面图。三步走——散点预览、网格插值、成图定型:
% 第一步:散点预览,先看采样覆盖是否均匀 xq = -3 + 6*rand(400,1); yq = -3 + 6*rand(400,1); zq = peaks(xq, yq) + 0.15*randn(400,1); scatter3(xq, yq, zq, 12, zq, 'filled'); % 第二步:插值到规则网格 [X, Y] = meshgrid(linspace(-3, 3, 80)); Z = griddata(xq, yq, zq, X, Y, 'cubic'); % 第三步:成图 figure surfc(X, Y, Z); shading interp; colorbar view(-37.5, 32); axis tight xlabel('X'); ylabel('Y'); zlabel('高度') exportgraphics(gcf, 'surface.png', 'Resolution', 300)
结果解读:griddata 的 cubic 插值给出光滑曲面但会在边界外推失真,linear 稳妥但面片感重;散点稀疏区域插值不可信,正式报告里应把这些区域用 NaN 遮掉(超出凸包的点天然为 NaN,surf 会留空,这是合理行为而不是 bug)。变式:把第三步换成 contourf(X, Y, Z, 20) 填色等高线,同一数据的二维呈现,期刊排版常常更欢迎后者。
三维绘图的高频报错有两类。维度不匹配:surf 要求 X、Y、Z 同尺寸,meshgrid 与 ndgrid 的输出排布不同,把 ndgrid 的结果喂给 surf 会得到尺寸错乱或扭曲的曲面——修法是 meshgrid 供绘图、ndgrid 供计算,或用 permute 转换。黑屏或纯色面:Z 的动态范围过小(如全部在 1e-3 量级)时默认色标分辨不出结构,caxis(新名 clim)手动拉伸映射区间即可。视角类问题不报错但更隐蔽:曲面背面遮挡主结构,除了转 view,还可以 alpha(0.8) 把面调成半透明,或直接 mesh 换透气网格。
两组概念边界要划清。网格数据与散点数据是"数据形态"之分:前者可 surf 直画,后者必须过 griddata 或散点专属的 scatter3/delaunay 路线。着色与高度是"映射通道"之分:默认颜色映射到 Z,但也可以映射到第四维数据(如温度场上叠加压力色标),surf(X, Y, Z, C) 中 C 与 Z 同尺寸即可——两个视觉通道各承载一个变量,是三维图少有的信息增益点,用得好一张图顶两张。
meshgrid 是三维绘图的入场券,散点数据先插值成网格;surf 实面、mesh 透气、contour 最可读,surfc 曲面加投影一步到位;view 两个角度定构图,满意后固化进代码;slice 切平面观察内部分布;