【Delft3D FM数据后处理系列】2. 模型地形图绘制的三种进阶可视化方案
2026/7/14 4:59:37 网站建设 项目流程

1. 科研绘图需求与工具选择

做水动力模型的朋友们应该都深有体会,Delft3D FM虽然功能强大,但它的可视化工具QuickPlot确实有点"简陋"。我在写第一篇SCI论文时就遇到了这个痛点——审稿人要求补充更专业的地形示意图,但QuickPlot输出的图表连基本的科研绘图标准都达不到。更糟的是,Deltares官方提供的OpenEarthTools我用了几次都没跑通,各种报错让人抓狂。这就是为什么我最终选择了Matlab+Surfer的组合方案。

这里要特别说明的是,Matlab负责数据处理和基础绘图,Surfer则用来做专业的地形渲染。这种分工非常合理:Matlab擅长处理NetCDF格式的模型输出文件,而Surfer在地形可视化方面有着不可替代的优势。举个例子,Matlab读取Map.nc文件只需要几行代码:

mapfilename = 'Boluo2map.nc'; lon = ncread(mapfilename,'mesh2d_node_x'); lat = ncread(mapfilename,'mesh2d_node_y'); FaceConnect = ncread(mapfilename,'mesh2d_face_nodes');

但说到绘制带光照效果的3D地形图,Surfer的操作界面和渲染引擎就友好多了。我建议初学者先掌握Matlab的基础数据处理,再逐步学习Surfer的高级功能。这种渐进式学习路径可以避免一开始就被复杂的参数设置吓退。

2. 网格地形结合图的Matlab实现

第一类地形图的特点是同时展示模型网格和地形特征,这在方法章节中非常实用。实现这个效果的关键在于正确处理三角网格和四边形网格的混合情况。Delft3D FM的Map.nc文件中,mesh2d_face_nodes变量就存储着这种混合网格信息。

实际操作中我发现一个细节问题:需要通过判断NaN值来区分三角形和四边形单元。下面这段代码展示了如何处理这种混合网格:

sn1 = find(isnan(FaceConnect(4,:))); % 三角形单元索引 sn2 = find(~isnan(FaceConnect(4,:))); % 四边形单元索引 % 绘制四边形单元 patch('Faces',FaceConnect(1:4,sn2)','Vertices',[lon lat],... 'CData',z,'EdgeColor','interp','FaceColor','none') % 绘制三角形单元 patch('Faces',FaceConnect(1:3,sn1)','Vertices',[lon lat],... 'CData',z,'EdgeColor','interp','FaceColor','none')

这里有几个实用技巧:

  1. 使用scatteredInterpolant将离散的xyz数据插值到网格节点上
  2. EdgeColor设为'interp'可以实现颜色渐变效果
  3. FaceColor设为'none'保持网格透明,突出地形特征

我建议在论文中使用这类图时,适当调整线宽和颜色映射。太细的网格线在打印稿中会看不清,而对比度不足的颜色映射在黑白打印时可能完全失效。通常我会用parula或者jet色图,线宽设置在0.5-1pt之间。

3. 纯地形图的绘制技巧

第二类纯地形图看似简单,但要画出专业感需要注意几个细节。核心仍然是patch函数,但这次我们要用mesh2d_flowelem_bl变量来表示地形高程。这个变量存储的是每个网格单元底部的高程值,直接对应着海底地形。

这里分享一个我踩过的坑:直接使用patch(lon,lat,bl)会导致图形错乱,必须通过FaceConnect正确地组织顶点数据。正确的绘制方法应该是:

% 绘制四边形单元地形 patch(lon(FaceConnect(1:4,sn2)),lat(FaceConnect(1:4,sn2)),bl(sn2)) % 绘制三角形单元地形 hold on patch(lon(FaceConnect(1:3,sn1)),lat(FaceConnect(1:3,sn1)),bl(sn1)) % 添加颜色条并设置标签 h = colorbar; ylabel(h,'Elevation (m)')

为了让地形图更直观,我通常会做这些优化:

  1. 设置合理的视角(view函数调整)
  2. 添加光照效果(light函数)
  3. 调整颜色映射范围以突出地形特征
  4. 添加比例尺和指北针

一个专业的小技巧是使用demcmap函数自动设置适合高程数据的颜色映射:

colormap(demcmap(bl))

4. 带等值线地形图的Surfer方案

第三类带等值线的地形图是论文中最常见的,但Matlab的patch函数在这方面确实力有不逮。这就是为什么我要引入Surfer——它在等值线绘制和白化处理上有着绝对优势。

Surfer的工作流程大致分为三步:

  1. 将xyz数据网格化(Grid → Data)
  2. 使用bln文件进行白化(Grid → Blank)
  3. 绘制等值线图(Map → Contour)

白化是个关键步骤,很多新手在这里会出错。简单来说,白化就是用一个多边形边界(bln文件定义)来限定有效数据区域。我通常这样准备bln文件:

  1. 用GIS软件导出研究区域的岸线多边形
  2. 用文本编辑器按bln格式保存(首行是点数,后面是坐标对)
  3. 确保多边形是闭合的

在Surfer中完成绘图后,我建议导出为EMF或PDF格式,这样在论文中可以保持矢量特性。如果需要对图形进行进一步编辑,可以:

  1. 导出Surfer图形到Adobe Illustrator
  2. 调整等值线标签位置
  3. 优化图例布局
  4. 添加自定义标注

这里有个实用技巧:在Surfer中先做好基础图形,再到AI中添加专业标注。这样既利用了Surfer的强大计算功能,又能获得出版级的图形质量。

5. 数据准备与文件格式处理

无论是用Matlab还是Surfer,正确处理输入文件都是成功的第一步。Delft3D FM的输出文件主要有两种格式需要处理:NetCDF(.nc)和ASCII(.xyz)。

对于NetCDF文件,Matlab的ncread函数是首选。但要注意Delft3D FM的变量命名规则可能随版本变化。我建议先用ncdisp查看文件结构:

ncdisp('Boluo2map.nc')

常见的变量包括:

  • mesh2d_node_x/mesh2d_node_y:节点坐标
  • mesh2d_face_nodes:网格连接关系
  • mesh2d_flowelem_bl:单元底部高程

对于xyz文件,有几个注意事项:

  1. 确保数据列顺序是经度、纬度、高程
  2. 检查坐标系统是否一致(建议全部用WGS84)
  3. 处理异常值(如-9999这样的占位符)

我通常会写一个预处理脚本来规范数据格式:

data = dlmread('raw_data.xyz'); data(data(:,3)==-9999,3) = NaN; % 处理异常值 dlmwrite('processed.xyz',data,'precision','%.6f') % 保持足够精度

6. 图形美化与出版级调整

最后完成的图形往往还需要一系列美化步骤才能达到出版要求。根据我的投稿经验,有几个常见的图形问题需要特别注意:

颜色映射选择

  • 地形图建议使用渐变色(如terrain或topo色图)
  • 避免使用彩虹色系(如jet),它们在科学可视化中已被诟病
  • 考虑色盲友好配色(如viridis或cividis)
colormap(turbo) % 新版Matlab推荐的色盲友好色图

字体和标签规范

  • 字体统一用Arial或Times New Roman
  • 字号不小于8pt(印刷品)
  • 坐标轴标签要带单位
  • 颜色条标题要明确

输出格式设置

  • 矢量图首选PDF或EPS
  • 分辨率至少600dpi(位图)
  • 保持宽高比符合期刊要求

一个实用技巧是使用exportgraphics函数控制输出质量:

exportgraphics(gcf,'figure.pdf','ContentType','vector')

记住,好的科学可视化不仅要准确反映数据,还要让读者一眼就能抓住关键信息。多参考顶级期刊中的类似图表,学习他们的可视化风格和技巧。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询