乐于分享
好东西不私藏

WPS模拟区域绘制

WPS模拟区域绘制

WRF · 绘图实战2026.07

能画出来就够了?

WPS模拟区域绘制

中国边界 · 兰伯特刻度 · 离散地形色标

plot_domains_mod.py

FrykitCartopy

📦 5 Parts + Conclusion

PART 01

官方更新

新增了什么

PART 02

修改思路

范围·边界·刻度

PART 03

运行教程

第一次运行

PART 04

静态场叠加

色标与变量

PART 05

参数速查

默认值与冲突

PART ///

写在最后

私信获取脚本

2026 年 7 月,WPS 4.7.0 正式发布。更新列表里有一项很对绘图党的胃口:官方新增了 Python 区域可视化脚本util/plot_domains.py,并明确说明它比传统的 NCL 脚本plotgrids_new.ncl提供了更完善的功能。

这意味着,配置完namelist.wps后,我们不必再单独折腾 NCL,就可以直接用 Python 检查嵌套关系、绘制 d01/d02/d03,甚至拿geo_em.d0*.nc做验证。但当我把它用在中国区域三层嵌套上时,第一张图还是让我有点难受:区域是对的,图却不够“顺眼”。于是,我在官方脚本思路的基础上重新生成了一版:plot_domains_mod.py

01

PART

WPS 4.7 带来了什么

UPDATE · 新增功能

官方plot_domains.py的核心输入是namelist.wps。脚本读取&share&geogrid中的网格数量、父子区域、网格距、起始格点及投影参数,然后在对应的地图投影上计算每个区域的位置。

除了画矩形,它还会检查几个容易被忽略的问题:子区域网格数是否满足嵌套比要求、子区域与父区域边界是否保留足够网格、同级区域是否发生重叠。加上-v后,还可以读取 geogrid 生成的geo_em.d0*.nc,用实际地理场验证区域位置

官方版本支持 WPS 常用的 LambertMercatorPolarLat-lon 投影,也保留了显示参考点、河流、区域信息和透视图等选项。对于“快速确认 namelist 有没有写错”这件事,它已经很好用了。

— WPS 4.7.0 官方 plot_domains.py 绘制的三层中国区域图

程序默认参数除了会在 d01 模拟区域外围额外拓展 10 层主网格作为留白,还会将参考点标记为红点,搭配诊断风格的区域标签、行政边界与经纬网。绘图默认输出的中国行政区域界线精度不足、边界绘制不够规范,并不适合直接用作汇报材料或期刊插图。

02

PART

修改思路

DESIGN · 修改思路

修改时保留了官方脚本的区域计算和嵌套检查逻辑,重点重写地图展示层。整体思路可以分成四步:先确定 d01 的图幅范围,再替换中国区域边界数据,随后处理不同投影下的经纬网和刻度,最后统一区域标签、边框与图层顺序。

第一步是固定主区域图幅。官方脚本的–border默认值为 10,会在 d01 四周各增加 10 个主网格的显示边距。新版将默认值改成 0,让地图边框直接贴合 d01;如果后续确实需要留白,仍然可以通过–border手动增加。

第二步是重构行政边界层级。新版引入 Frykit,分别添加陆地、海洋、全球国界、中国国界、省界和九段线,并根据重要程度设置不同线宽与颜色。国界和省界还增加了浅色外描边,这样叠加地形后,行政边界也不会淹没在色块里。中国区域图右下角默认补充南海小图;叠加geo_em静态场时,小图使用与主图一致的填色设置。

第三步是把底图数据和投影刻度分开处理。严格来说,兰伯特投影的经纬网和刻度标签并不是直接由 Frykit 绘制:经纬网由 Cartopy 的gridlines生成;刻度位置则由新脚本借鉴 Frykit 的边界求交思路,使用 Cartopy 投影和 Shapely 计算经纬线与地图下边界、左边界的交点,再格式化为经纬度标签。Frykit 在这里主要负责陆地、海洋、中国国界、省界和附属线。顶部和右侧刻度默认关闭,使画面保持简洁。

— 使用 Frykit 改写后的无地形三层区域图

第四步是统一视觉层级。新版取消默认标题和红色参考点,将三个区域统一标成黑色的 d01、d02、d03;字号默认增大到 13,标签背景使用半透明白色;嵌套边框增加白色衬底,避免与省界、海岸线混在一起。

03

PART

准备脚本与第一次运行

USAGE · 运行教程

下面默认已经进入能够正常导入 Matplotlib、Cartopy、Frykit、NumPy、Shapely 和 netCDF4 的 Python 环境。如果提示缺少依赖,再按需安装即可:

...bash

pip install matplotlib cartopy frykit numpy shapely netCDF4 f90nml

先画不带地形的区域图:

...bash

MPLBACKEND=Agg python plot_domains_mod.py \

-n namelist.wps \

–grid_interval 10 \

–save_file domains.png

MPLBACKEND=Agg适合服务器和无桌面环境,脚本会直接保存图片而不弹出窗口。–grid_interval 10表示主经纬网间隔为 10°。不写–title时不显示标题,默认–border 0,因此图幅与 d01 对齐。

如果希望区域标签同时显示网格距、物理尺寸、父区域起点和网格数,可以使用:

...bash

python plot_domains_mod.py \

-n namelist.wps \

–info 15 –outline_text \

–save_file domains_with_info.png

这里可以把–info理解成四个独立的信息开关,每个开关都有一个固定数值:

数值
打开后显示的信息
1
网格距dx/dy
2
区域的实际物理尺寸
4
子区域在父区域中的起始格点
8
区域的东西向和南北向网格数

想显示哪些信息,就把对应数字相加。例如,只显示网格距和网格数时,使用–info 9,因为 1 + 8 = 9。示例命令使用–info 15,是因为 1 + 2 + 4 + 8 = 15,表示四个开关全部打开。–info 0则表示不显示这些附加信息。

— 使用 info 15 显示全部区域信息的效果图

04

PART

叠加 geo_em 静态场

GEODATA · 静态场叠加

运行 geogrid 后,通常会得到geo_em.d01.ncgeo_em.d02.ncgeo_em.d03.nc。这些文件不只有地形,还保存了海陆分布、土地利用类型、雪反照率等静态地理场。把它们和namelist.wps放在同一目录,通过-v开启叠加,再用–verify_field选择变量:

...bash

MPLBACKEND=Agg python plot_domains_mod.py \

-n namelist.wps \

-v \

–verify_field HGT_M \

–colorbar_orientation vertical \

–save_file domains_terrain.png

脚本只接受与XLAT_MXLONG_M尺寸一致的二维质量网格变量。变量不存在或维度不匹配时,会直接列出当前geo_em中可以叠加的字段。

四种地形色标怎么选

地形仍使用contourf,但颜色不是连续渐变,是由BoundaryNorm划分为离散高度区间。新版提供四个可直接选择的地形预设:

色标预设
特点
单位
terrain_m
经典绿—黄—棕—白,地形起伏直观
m
bluegreen_m
蓝绿—深蓝—紫,适合清爽的中国区域图
m
earth_m
低饱和自然地貌色,整体更沉稳
m
gray_m
灰度层级,适合论文底图和后期叠加
m

四种预设使用相同的实际高度边界:0、200、500、1000、1500、2000、2500、3000、4000、5000、6000 m。

— 四种地形离散色标的三层模拟区域对比

–colorbar_style有四个可选值:terrain_mbluegreen_mearth_mgray_m。运行时任选一个,例如:

...bash

python plot_domains_mod.py -n namelist.wps -v \

–colorbar_style terrain_m –colorbar_orientation horizontal \

–save_file terrain_m.png

这四个预设只适用于HGT_M,高度边界、自定义levelsvmin/vmax全部统一使用米。水平色标与主图等宽,垂直色标与主图等高。

cmap、levels 和 vmin/vmax 分别控制什么

这几个参数可以按“预设、颜色、分段、范围”来理解:

参数
实际控制内容
–colorbar_style
一整套预设:颜色、单位和默认分段
-c, –cmap
只更换颜色方案,不改变数值区间
–levels
精确指定每个离散色块的边界
–vmin, –vmax
指定自动色标的起止范围,中间自动等分为 10 个色块

例如,下面的命令使用 Matplotlib 的viridis调色板,同时手动指定不等距的地形分段:

...bash

python plot_domains_mod.py \

-n namelist.wps -v \

-c viridis \

–levels 0,200,500,1000,2000,3000,6000 \

–save_file domains_terrain_custom_levels.png

— viridis 调色板与非等距地形分段的绘图效果

如果只关心 0–3000 m 的地形差异,不需要自己列出每一级,可以写成:

...bash

python plot_domains_mod.py \

-n namelist.wps -v \

-c cividis \

–vmin 0 –vmax 3000 \

–save_file domains_terrain_0_3000m.png

这时脚本会在 0–3000 m 之间自动生成 10 个等宽色块。–levels的优先级更高,因此不能与–vmin–vmax同时使用。四种地形预设的数值单位都是米。

除了地形,还能叠加什么

LANDMASKLU_INDEX属于分类变量,新版为它们增加了专门处理:LANDMASK固定显示 0 水体和 1 陆地;LU_INDEX根据数据中的整数类别生成离散色块,色标显示类别编号。分类变量不能再传入–levels–vmin–vmax,但仍可用-c更换配色。

...bash

python plot_domains_mod.py \

-n namelist.wps -v \

–verify_field LANDMASK \

–colorbar_orientation horizontal \

–save_file domains_landmask.png

python plot_domains_mod.py \

-n namelist.wps -v \

–verify_field LU_INDEX \

–colorbar_orientation horizontal \

–save_file domains_lu_index.png

— LANDMASK 与 LU_INDEX 静态地理场对比

LU_INDEX图上的数字是土地利用类别编号,具体含义由 geo_em 的全局属性 MMINLU 决定。脚本只在色标上显示编号,是因为 MODIS 和 USGS 的同一编号可能代表完全不同的地表类型。可以先用下面的命令确认分类方案:

...bash

ncdump -h geo_em.d01.nc | grep -E “MMINLU|NUM_LAND_CAT|ISWATER|ISLAKE”

本文使用的三层geo_em均为MODIFIED_IGBP_MODIS_NOAH,共 21 类:水体为 17,城市为 13,冰雪为 15,湖泊为 21。完整对照如下:

编号
MODIS/IGBP-Noah 地表类型
1
常绿针叶林
2
常绿阔叶林
3
落叶针叶林
4
落叶阔叶林
5
混交林
6
郁闭灌丛
7
稀疏灌丛
8
木本稀树草原
9
稀树草原
10
草地
11
永久湿地
12
农田
13
城市和建设用地
14
农田/自然植被镶嵌
15
冰雪
16
裸地或稀疏植被
17
水体
18
木本苔原
19
混合苔原
20
裸地苔原
21
湖泊

编号 1–20 的含义依据WRF 官方 MODIS 土地利用分类表;第 21 类湖泊由本文geo_em中的ISLAKE=21以及WPS 输出属性说明确认。如果自己的MMINLU不是MODIFIED_IGBP_MODIS_NOAH,应查询对应分类表,不能直接套用上表。

不同的 geog 数据配置会生成不同变量,常见字段可以这样理解:

变量
含义
建议用法
HGT_M
地形高度
使用四种地形预设之一
LANDMASK
海陆掩膜,0 水体、1 陆地
脚本自动使用海陆双色
LU_INDEX
主导土地利用类别
脚本自动使用分类色标
SNOALB
最大积雪反照率,百分比
可用-c Blues –levels 0,10,…,90
CLAYFRAC
黏土比例
可用-c YlOrBr –vmin 0 –vmax 1
SANDFRAC
沙土比例
可用-c YlOrBr –vmin 0 –vmax 1
MAPFAC_M
质量网格地图比例因子
可用默认viridis自动范围

需要注意,geo_em保存的是静态地理场,不包含T2、降水、风场等模拟结果;这些变量位于wrfout。像LANDUSEF这样额外包含土地利用类别维度的多层变量,目前也不能直接叠加。

05

PART

常用参数速查

PARAMETERS · 参数速查

参数
默认值
用途与示例
-n, –namelist ./namelist.wps
指定 WPS namelist 文件
-s, –save_file domains.png
指定输出图片路径
–dpi 220
保存分辨率,印刷图可提高到 300
-b, –border 0
d01 外扩的主区域网格数;设为 5 即四周多 5 格
-f, –fontsize 13
d01/d02/d03 标签字号
–title
设置图题;空字符串表示隐藏
–grid_interval 10
主经纬网间隔,单位为度
–minor_ticks 1
相邻主刻度之间的小刻度数量;0 表示关闭
–china_data_source tianditu
Frykit 中国边界来源,可选tianditu(来源于天地图行政区划数据服务amap(来源于高德地图行政区域查询 API
–no_china
关闭
不绘制强调的中国国界、省界和附属线
–no_south_china_sea
关闭
关闭右下角南海小图;中国区域图默认保留
-hb,–hide_borders
关闭
隐藏国界
-hl, –hide_lines
关闭
隐藏省界
-i, –info 0
标签信息位掩码:1 网格距、2 物理尺寸、4 父区起点、8 网格数
-o,–outline_text
关闭
为区域文字增加白色描边
-v, –verify
关闭
读取geo_em.d0*.nc并叠加验证场
–geogrid_dir
namelist 目录
指定geo_em文件所在目录
-vf, –verify_field
HGT_M
指定二维质量网格变量;分类变量专门适配 LANDMASK、LU_INDEX
-c, –cmap
auto
仅更换 Matplotlib 颜色方案;如 viridis、cividis、Blues
–colorbar_style
default
地形可选 terrain_m、bluegreen_m、earth_m、gray_m;其他变量使用 default
–colorbar_orientation vertical
色标方向,可选垂直或水平
–levels
自动
精确指定逗号分隔的递增边界,不能与 vmin/vmax 同用
–vmin, –vmax
数据范围
自动色标的起止值;缺少一端时使用数据范围补齐
–f90nml
关闭
使用可选的f90nml读取 namelist
–ignore_verification
关闭
嵌套检查失败后仍继续绘图

常用组合可以记成三档:只看区域用基础命令;–fontsize–grid_interval–dpi;检查 geogrid 时加-v–geogrid_dir与色标参数。

如果图面太密,可以先把–minor_ticks设为 0,再适当增大–grid_interval;如果只想保留全球底图而不突出中国边界,可使用–no_china-hb会隐藏国界,-hl会隐藏省界,两者控制的对象不同。–f90nml不是必选项,脚本自带的读取器可以处理常见 WPS namelist;只有遇到更复杂的 Fortran namelist 写法时,才建议安装并启用 f90nml。

///

LAST

写在最后

CONCLUSION · 写在最后

脚本获取:可以私信“模拟区域绘制”。