WRF数据处理从安装到绘图:wrf-python与cartopy实战指南

发布时间:2026/10/28 5:58:01

WRF数据处理从安装到绘图:wrf-python与cartopy实战指南 简介数值天气预报输出的NetCDF文件包含海量物理量科研与工程项目中常需提取变量、插值到等压面并完成可视化。此类后处理依赖wrf-python等Python库而其Fortran扩展在安装时对编译器和NetCDF依赖要求严格常成入门障碍。掌握依赖管理、conda环境隔离以及基于cartopy的投影绘图流程可显著提升WRF数据使用效率。本文从源码包特征出发解析安装避坑要点给出读取变量、等压面插值、站点坐标转换和批量出图的完整方案帮助气象与环境领域从业者快速上手wrf-python打通从模式输出到业务图表的最后一公里。1. 从 tar.gz 到第一张 WRF 图为什么最卡的是安装做气象、环境预报或风资源评估的人对“wrfout_d01_……”这一串 NetCDF 文件八成不陌生。WRF 模式跑完后几百个变量和几十个时次堆在一起要读其中某个物理量、插到 850hPa再配一张带地图投影的图前后处理的时间经常比模式运行时间还长。wrf-python 1.1.3 就是用来顶替这段手工劳动的库它提供读取 WRF 输出、去交错、等压面插值、诊断量计算和 cartopy 投影的一整套 Python 接口。但这个库有个特点作为 tar.gz 源码包它需要在目标机器上现场编译 Fortran 扩展本机编译器和 NetCDF 库缺一不可不少人在安装阶段就被劝退。这篇笔记从下载包开始把依赖、安装、读取、插值、出图和常见报错一次讲完。2. 安装前先做三个判断版本、解释器、依赖从哪来2.1 认清 tar.gz 里的东西Python 源码、Fortran 扩展和一堆依赖wrf-python-1.1.3.tar.gz 在 PyPI 上属于 sdist源码发行包不是 wheel。它里面包含 Python 源代码、setup.py以及用 Fortran 写的数值内核。以 1.1.3 发布时的生态来看这套内核需要 f2py 在目标机器上现场编译系统里必须同时有 C 编译器、Fortran 编译器和 NetCDF 的 C/Fortran 两套库。漏掉任何一项都会在 pip install 阶段以奇怪的链接错误收场。我一般会先跑一遍下面的命令把关键依赖的版本一次性看清# 查看编译器是否可用 gcc --version gfortran --version # 查看 NetCDF C 库 nc-config --all # 查看 NetCDF Fortran 库这个最容易漏装 nf-config --all说明gcc 和 gfortran 是编译 Fortran 扩展的基础nc-config 来自 netcdf-cnf-config 来自 netcdf-fortran二者返回的头文件路径与库路径会写进 setup.py 的构建参数。如果 nf-config 不存在源码安装基本注定失败这是最常见的一处坑后面避坑章会再细说。常见发行版的安装命令如下命令行参数的含义就是让系统把开发头文件一并装上避免“库找到了但头文件找不到”的尴尬局面# Ubuntu / Debian sudo apt install gcc gfortran libnetcdf-dev libnetcdf-fortran-dev # macOS 用 Homebrew 时 brew install gcc netcdf netcdf-fortran此外wrf-python 1.1.3 在 Python 端的依赖一般包含 numpy、scipy、matplotlib、netCDF4、xarray、cartopy、wrapt、six。重量级的是 cartopy它会带着 geos、proj、shapely、pyproj 一起装。所以安装思路很明确能用 conda 让依赖统一解析就不要让 pip 盲目拉取“当前最新版”否则 cartopy 新版本和 1.1.3 的兼容性会变成新的难题。依赖项可以按下表核对编译器看 gcc/gfortran读 NetCDF 看 netcdf-cFortran 接口看 netcdf-fortranPython 侧则让 conda 或 pip 自动解析。检查的重点其实是 netcdf-fortran很多人装完 netcdf-c 就以为万事大吉结果编译到一半才报错。依赖检查命令缺失时的典型后果GCCgcc --versionf2py 无法编译 C 部分GFortrangfortran --versionFortran 内核无法构建netcdf-cnc-config --all找不到 netcdf 头文件netcdf-fortrannf-config --all链接时找不到 libnetcdffPython 3.8python --version1.1.3 在 3.8 下最稳3.9 要额外折腾2.2 优先用 conda 建隔离环境pip 源码安装做后手实际项目里我几乎不会直接把 wrf-python 装进 base 环境。因为同一个机器上还可能有 TensorFlow、GPU 驱动对应的 numpy 版本wrf-python 又对 numpy 和 cartopy 有版本要求混在一起很容易把环境搞坏。常见做法是单独建一个干净环境锁死 Python 版本# 创建 Python 3.8 的独立环境 conda create -n wrf python3.8 -y # 进入环境 conda activate wrf # 从 conda-forge 安装 wrf-python 1.1.3 conda install -c conda-forge wrf-python1.1.3 -y解释一下参数python3.8是刻意指定的wrf-python 1.1.3 发布时主要验证到 3.8用 3.8 能少踩 f2py 在更新解释器上的兼容坑-c conda-forge告诉 conda 去社区频道找预编译包而不是自己从源码构建。conda 会把 netcdf4、cartopy、numpy 等依赖按频道内互相兼容的版本统一解析这是 pip 做不到的。只有以下几种情况我才会用 tar.gz 源码安装内网机器无法访问 conda 频道或者公司要求所有 Python 依赖必须走 pip 的私有源。源码安装的前提是 2.1 节那条检查命令全部通过然后执行# 如果 nc-config/nf-config 不在 PATH 里先指一下目录 export NETCDF_DIR/usr/local # 在当前目录下直接构建安装 pip install wrf-python-1.1.3.tar.gzNETCDF_DIR 的作用是告诉 setup.py 到哪里去找 NetCDF 的头文件和库文件。常见错误是只设了 NETCDF_DIR 却忘了 Fortran 接口或者系统里有多个 NetCDF 版本导致路径指向混乱这些坑在第五章会专门讲。2.3 内网机器或离线环境先下载全部依赖再分发科研内网经常不让直接访问外网包源此时分两步走。第一步在外网开发机上用 pip download 把源码包和依赖都拉下来# 把 wrf-python 及其依赖下载到指定目录 pip download wrf-python1.1.3 --no-deps -d ./wheels pip download cartopy0.18.0 netCDF41.5.3 -d ./wheels第二步把整个 wheels 目录拷到内网机器然后离线安装# 离线安装时禁止访问外网索引只从本地目录找包 pip install wrf-python-1.1.3.tar.gz --no-index --find-links./wheels这里的血泪经验是直接把 tar.gz 拷到内网机器再运行 pip install 不算完整方案因为 pip 一旦发现缺依赖仍然会去外网索引查询超时后整体失败。只有把依赖全部备齐离线安装才顺畅。如果内网允许用 conda更舒服的方式是外网机器上conda-pack整个 wrf 环境打包过去但那属于环境迁移不是安装适合一劳永逸的场景。装完以后验证一下# 验证导入和版本 python -c import wrf; print(wrf.__version__)能看到 1.1.3 且不报 ImportError说明基础安装完成。此时再拿一个 WRF 输出文件做冒烟测试确认能读到变量python -c from netCDF4 import Dataset; import wrf; print(wrf.getvar(Dataset(wrfout_d01_2019-07-01_00:00:00), T2, timeidx0).shape)输出一个二维 shape 才对例如(399, 399)或(100, 100)代表南北和东西方向格点数。如果这一步就报错说明读取层有问题继续往下看第三章。3. 读取 WRF 输出并插值到等压面最小可运行代码3.1 用 netCDF4.Dataset 当入口别把 xarray 直接塞进去wrf-python 的 getvar 接口对输入对象有要求它认 netCDF4 的 Dataset 对象也认 PyNIO 的 NioFile但不认裸的 xarray DataArray。这一点是新手最容易翻车的地方。很多人用 xarray 打开 wrfout 文件后顺手把 DataArray 传给 getvar结果报错或返回的坐标信息缺失。正确做法是明确以 netCDF4.Dataset 打开文件from netCDF4 import Dataset import wrf # WRF 输出文件通常以 wrfout_ 开头 ds Dataset(wrfout_d01_2019-07-01_00:00:00) # 读取 2 米温度timeidx0 表示取文件的第一个时次 t2 wrf.getvar(ds, T2, timeidx0) # 返回值是 xarray DataArray带维度、单位和投影信息 print(t2.shape) # 二维(south_north, west_east) print(t2.units) # K print(t2.dims) # 能看到维度名确认没有意外排序 ds.close()参数说明timeidx0取第一个时次timeidx-1取最后一个时次对于多层变量返回的数组是三维(bottom_top, south_north, west_east)二维变量则是(south_north, west_east)。注意这里变量名 “T2” 是 wrf-python 事先定义好的短名不是文件里的原始变量名。原始变量名可能是T2但更多时候像U、V、PH这种需要去交错和计算才能用的量wrf-python 在 getvar 内部帮你处理了所以别自己去文件变量列表里找同名变量。ds.close() 这行不能省。尤其后面批量处理几十个文件时不关闭句柄会导致文件描述符耗尽报 too many open files。多进程场景下更要小心每条进程都要独立打开文件不能把一个 Dataset 对象传递给子进程这个问题第五章会展开。3.2 一次 getvar 拿到三维场再用 interplevel 插到等压面读取单个二维变量只是热身。真正提高效率的是读取完整三维气压场和风场然后一次性插值到想要的等压面。WRF 原始文件里的竖向坐标是地形追随坐标气压层不是现成的需要先计算气压再做垂直插值。最小代码长这样from netCDF4 import Dataset import numpy as np import wrf ds Dataset(wrfout_d01_2019-07-01_00:00:00) # 读取完整气压场Pa三维 p wrf.getvar(ds, pressure, timeidx0) # 读取水平风场ua/va 是 WRF 质量格点上的风分量 ua wrf.getvar(ds, ua, timeidx0) va wrf.getvar(ds, va, timeidx0) # 插值到 850hPa注意单位是 Pa不要写成 850 u_850 wrf.interplevel( fieldua, vertp, desiredlev85000.0, missingwrf.default_fill(ua.dtype), ) v_850 wrf.interplevel( fieldva, vertp, desiredlev85000.0, missingwrf.default_fill(va.dtype), ) # 合成风速 wspd_850 np.sqrt(u_850**2 v_850**2) print(wspd_850.shape) ds.close()逻辑说明pressure变量由 wrf-python 根据 WRF 的气压诊断关系计算得到单位 Pa不是 hPaua和va是从交错的 U、V 场去交错后的质量格点风单位 m/s。interplevel 把三维场沿垂直方向线性插值到指定气压层核心参数有三个field是被插值的三维场vert是同 shape 的三维气压场desiredlev是目标气压值必须和 vert 单位一致。参数说明里最容易错的是missing。很多人习惯写np.nan但 Fortran 内核内部用 NetCDF 的_FillValue语义处理缺测类型不匹配时容易踩雷。wrf-python 提供了wrf.default_fill(dtype)它会按数据类型返回合适的填充值float 场就用-9999.0这类特定值绘图前用wrf.to_np()转回 numpy 数组时再处理掩膜。另一个常见问题是乱传维度如果 field 是(Time, bottom_top, south_north, west_east)的完整四维场但 vert 只取了某个 timeidx 的三维场shape 对不上interplevel 会报维度错误。getvar 返回的 timeidx 指定结果已经是去掉 Time 维的三维数组所以这里不需要再加索引。3.3 经纬度坐标转换用 ll_to_xy 匹配站点位置WRF 网格的索引和经纬度不是一一对应关系因为大多数 wrfout 都采用 Lambert 投影或极地投影。做站点验证时你需要把一个站点的经纬度换算成网格索引才能提取该点的模式值反过来想知道某个网格点对应什么经纬度就用 latlon_coords。from netCDF4 import Dataset import wrf ds Dataset(wrfout_d01_2019-07-01_00:00:00) t2 wrf.getvar(ds, T2, timeidx0) # 获取每个网格点的经纬度 lats, lons wrf.latlon_coords(t2) # 把站点经纬度换算为网格索引 x, y x, y wrf.ll_to_xy(ds, 30.1, 115.6) print(网格索引 x, y:, x, y) print(对应经纬度:, lats[y, x], lons[y, x]) ds.close()参数说明ll_to_xy的入口是 Dataset 对象因为投影信息存放在文件的 global attributes 中包括 MAP_PROJ、CEN_LAT、CEN_LON、STAND_LON 等DataArray 里并不携带这些元数据所以别拿 t2 去调用。返回的 x、y 是浮点索引实际提取时要取整或者用双线性插值获取更精确的站点值。这里有一个容易忽略的边界坑站点如果落在模拟区域外ll_to_xy 不会报错而是返回超出网格范围的索引。所以提取后要检查索引是否在0 x lons.shape[1]和0 y lats.shape[0]范围内。我习惯把这一步做成一个防御函数索引越界时直接返回 None避免后续数组越界引起整个脚本崩溃。这也是后面自动化批量处理能稳定跑完的前提之一。4. 用 cartopy 把变量画成平面图四个必调参数4.1 四步套路投影、范围、数据、图层wrf-python 出图最大的优势是投影坐标不用自己算。它提供了get_cartopy、cartopy_xlim、cartopy_ylim三个函数能从 DataArray 的元数据里直接生成 cartopy 的投影对象和范围。画一张等值线/填色图只需要按固定套路走取投影、定范围、传数据、叠加地理要素。import matplotlib.pyplot as plt import cartopy.crs as crs from netCDF4 import Dataset import wrf ds Dataset(wrfout_d01_2019-07-01_00:00:00) # 读取海平面气压 slp wrf.getvar(ds, slp, timeidx0) # 第一步获取 cartopy 投影对象 cart_proj wrf.get_cartopy(slp) # 第二步用 wrf 自带函数取 x/y 范围 xlim wrf.cartopy_xlim(slp) ylim wrf.cartopy_ylim(slp) # 第三步创建带投影的坐标轴 fig, ax plt.subplots( 1, 1, subplot_kw{projection: cart_proj}, figsize(10, 7), ) # 第四步叠加地图要素并填色 ax.coastlines(linewidth0.8) ax.set_extent([xlim[0], xlim[1], ylim[0], ylim[1]], crscart_proj) # 把经纬度网格交给 cartopy用 PlateCarree 变换到投影坐标系 lats, lons wrf.latlon_coords(slp) cf ax.contourf( lons, lats, wrf.to_np(slp), levels20, cmapSpectral_r, transformcrs.PlateCarree(), ) fig.colorbar(cf, axax, shrink0.8) fig.savefig(slp.png, dpi150, bbox_inchestight) plt.close(fig) ds.close()四个必调参数的核心作用get_cartopy(slp)读取 DataArray 里的投影元数据生成与 WRF 网格匹配的投影坐标轴省去手写 Lambert 投影参数cartopy_xlim和cartopy_ylim计算模拟域在投影坐标系中的物理边界直接喂给set_extent避免图幅过大或裁掉模拟域边缘transformcrs.PlateCarree()告诉 cartopylons/lats 是以经纬度形式给出的原始数据坐标必须经过投影变换wrf.to_np(slp)则是把 DataArray 转成 numpy 数组因为部分 matplotlib 版本对 xarray 的传递兼容性不够稳。有个细节值得注意这里没有直接用transformcart_proj并只传二维数组而是显式传 lons/lats 加PlateCarree。如果网格间距很小两者视觉差异不大但当你只传二维数组而不传坐标时cartopy 会把数组索引当成投影坐标容易得到一张偏移的图这在新版 cartopy 里尤其坑。显式传经纬度虽然慢一点但结果不会骗你。4.2 批量出图时timeidx 与文件句柄怎么管理实际业务中不可能只画一张图。跑完一次 72 小时预报至少 72 个时次每个时次可能还要出风场、温度、气压多张图。批量循环时最容易犯两个错误一是循环里反复调用Dataset()但从不 close二是把同一个 Dataset 对象在多个函数间传递后忘记时次对应关系。import glob from netCDF4 import Dataset import wrf # 按文件名排序保证时次顺序 file_list sorted(glob.glob(wrfout_d01_2019-07-01_*)) for idx, f in enumerate(file_list): # 每个文件单独打开用完即关 ds Dataset(f) # 取最后一个时次通常是该文件的预报时刻 t2 wrf.getvar(ds, T2, timeidx-1) # 这里可以继续做插值、绘图等操作 ds.close()逻辑说明有些 WRF 输出是每 6 或 12 小时写一个文件每个文件里包含多个累积时次有些则是一个时次一个文件。用glob和sorted能保证文件读取顺序稳定。timeidx-1表示取文件内最后一个时次对单时次文件来说就是唯一时刻对多时次文件来说正好是文件对应的预报时刻这是最省心的一种写法。批量出图还有一个经常出现的小麻烦如果每张图的标题写的是 UTC 时间且长度不一图下方的横坐标文字挤成一团。这个“python 画图横坐标太密集”的问题在时间序列图里尤其明显。处理方法有两种一是把时间字符串转成 datetime 后用 matplotlib 的日期格式化器控制刻度间距二是直接用fig.autofmt_xdate()旋转日期标签。后者一行代码能解决 80% 的密集问题from matplotlib.dates import DateFormatter ax.xaxis.set_major_formatter(DateFormatter(%m-%d %H:%M)) fig.autofmt_xdate()如果横坐标上不是日期而是站点编号或文件名更简单的做法是用ax.set_xticks([0, 5, 10, 15])手动限制定点数量别让 matplotlib 自动塞满所有刻度。这一行代码在网格站点很多时非常管用。5. 避坑安装与运行中最常见的 5 个报错5.1 源码编译报 cannot find -lnetcdff现象执行pip install wrf-python-1.1.3.tar.gz时编译过程在最后链接阶段报错cannot find -lnetcdff或者类似ld returned 1 exit status。原因-lnetcdff是链接器对 netcdf-fortran 库的缩写引用。系统里装了 netcdf-c 并不代表有 netcdf-fortran后者是 NetCDF 的 Fortran 接口库wrf-python 的 Fortran 内核需要它来完成 NetCDF 读写。解决先确认nf-config --version能正常输出版本装不上就用系统包管理器安装左面 2.1 节里那条 Ubuntu 安装命令已经包含。安装后再把NETCDF_DIR环境变量指向包含 include 和 lib 的公共前缀目录例如/usr/local避免 f2py 找不到头文件。5.2 conda 环境里 import wrf 报 libnetcdff.so 找不到现象用 conda 安装后执行import wrf报错提示libnetcdff.so.6: cannot open shared object file或类似动态库缺失。原因conda 环境里的动态库搜索路径没有包含 netcdf-fortran 的库目录或者安装时 conda 只装了 Python 包没有把配套的 netcdf-fortran 库作为显式依赖拉进来。解决在同一个环境里补齐 netcdf-fortran让动态库路径统一conda install -c conda-forge netcdf-fortran -y装完再用ldd检查一下 wrf 扩展到底依赖哪个路径的库python -c import wrf; print(wrf.__version__)如果还报错可以考虑conda install -c conda-forge compilers这会把与 conda 环境兼容的编译器工具链补齐避免运行时链接到系统目录里版本不一致的 libnetcdff。5.3 把 xarray 传给 getvar 报 Wrong number of dimensions现象用xr.open_dataset()读文件后取某个变量传给wrf.getvar()报错维度数不对或者返回的数组维度和文件原始维度完全错乱。原因wrf-python 内核在解析输入时依赖文件级全局属性和维度顺序xarray Dataset 虽然能读 NetCDF但它并不在上面的接口协议里。直接传 DataArray 等于绕过了 wrf-python 预期的文件句柄逻辑。解决统一用netCDF4.Dataset打开文件再传给 getvar。如果项目里已经用 xarray 做了大量预处理不要硬传给 wrf-python先把需要的时次切片单独写成临时 nc 文件再用 netCDF4.Dataset 打开流程更稳import xarray as xr from netCDF4 import Dataset import wrf ds_xr xr.open_dataset(wrfout_d01_2019-07-01_00:00:00) # 只保留一个时次避免文件过大 ds_xr.isel(Time0).to_netcdf(tmp_one_time.nc) ds Dataset(tmp_one_time.nc) t2 wrf.getvar(ds, T2, timeidx0) ds.close()5.4 多进程并发处理同一份 WRF 文件崩溃现象用 multiprocessing 池并行处理不同时次或不同区域时子进程随机崩溃报错信息指向 Fortran 层的段错误或非法访问。原因wrf-python 的 Fortran 扩展在 1.1.3 版本上并不是完全线程安全的而且 NetCDF 的文件句柄也不能跨进程直接继承。多个进程同时读同一个 Dataset 对象底层缓冲区和文件指针会互相覆盖。解决每个子进程内部独立打开文件不要把父进程的 Dataset 当参数传进去。常见做法是子进程只接收文件路径打开文件、处理、关闭全在进程内完成def process_one(path): ds Dataset(path) # 必须在子进程内打开 t2 wrf.getvar(ds, T2, timeidx-1) ds.close() return t2.mean().values如果每个任务还要读取区域附近的多层变量尽量让输入区域小一点。Fortran 侧在处理大数组时会做很多内部复制内存占用往往是 numpy 数组自身的两三倍这也是并发场景下容易 OOM 的一个隐藏原因。5.5 pip 和 conda 混装后cartopy 版本被拉高绘图行为异常现象conda 环境里已经装好 wrf-python之后又用 pip 装了个新包pip 顺手把 cartopy 升级到较新版本接下来绘图时ax.set_extent、gridlines或contourf行为诡异与之前的图明显不一致。原因wrf-python 1.1.3 对 cartopy 的接口依赖停留在较老版本新版 cartopy 对投影坐标和 matplotlib 接口做了调整。pip 安装依赖时会选择满足该新包要求的最新版 cartopy在同一环境中覆盖 conda 解析好的旧版本。解决不要在同一环境混用 pip 和 conda 管理同一批依赖。要升级别的包时先固定 wrf-python 相关依赖再操作或者直接新建环境。最稳妥的做法conda list | grep cartopy # 如果看到版本明显超过 0.18/0.19就回到干净环境重装 conda create -n wrf python3.8 -y conda install -c conda-forge wrf-python1.1.3 netcdf-fortran -y6. 进阶把出图函数封装成能跑 72 小时的批量工具6.1 函数本体把前面的读取、插值、绘图逻辑收拢成一个函数输入文件路径、变量名、等压面高度和输出路径返回生成好的图片路径。这个函数可以直接放进气象业务脚本或定时任务里。import os import matplotlib.pyplot as plt import cartopy.crs as crs from netCDF4 import Dataset import wrf def plot_wrf_var(nc_path, varname, level_hpaNone, out_pngout.png, cmapviridis): 读取 wrfout 文件绘制变量平面图支持插值到指定等压面 ds Dataset(nc_path) # 读取变量取文件最后一个时次 field wrf.getvar(ds, varname, timeidx-1) # 如果指定了等压面高度则先插值 if level_hpa is not None: p wrf.getvar(ds, pressure, timeidx-1) field wrf.interplevel( field, p, float(level_hpa) * 100.0, missingwrf.default_fill(field.dtype), ) # 投影、范围、绘图 cart_proj wrf.get_cartopy(field) xlim wrf.cartopy_xlim(field) ylim wrf.cartopy_ylim(field) lats, lons wrf.latlon_coords(field) fig, ax plt.subplots( 1, 1, subplot_kw{projection: cart_proj}, figsize(10, 7) ) ax.coastlines(linewidth0.8) ax.set_extent([xlim[0], xlim[1], ylim[0], ylim[1]], crscart_proj) cf ax.contourf( lons, lats, wrf.to_np(field), levels20, cmapcmap, transformcrs.PlateCarree(), ) fig.colorbar(cf, axax, shrink0.8) fig.savefig(out_png, dpi150, bbox_inchestight) plt.close(fig) ds.close() return out_pngPython 定义函数时把接口参数设计成文件路径而不是文件对象是批量任务稳定性的关键。这个函数有三个要点level_hpaNone时直接画地面量或二维量float(level_hpa) * 100.0负责把用户习惯的 hPa 转成 wrf-python 内部的 Paplt.close(fig)和ds.close()保证批量循环不泄漏文件句柄和内存。6.2 批量调用与结果验证配合现成的切片循环72 小时的图可以一次性跑完import glob file_list sorted(glob.glob(wrfout_d01_2019-07-01_*)) for nc_path in file_list: # 用文件名前缀生成输出文件名便于时间排序 tag os.path.basename(nc_path).replace(wrfout_, ) plot_wrf_var( nc_path, varnameT2, level_hpaNone, out_pngfT2_{tag}.png, cmapRdYlBu_r, )参数说明函数内部每次都会重新打开 Dataset这比传句柄安全也不会出现多进程并发时句柄互踩的问题。批量跑完后验证不要只看图选一个时次用 ll_to_xy 提取站点值和自动站观测或再分析资料对比一下确认插值结果在合理范围内。画图正确不代表数值正确尤其是等压面插值很多“看起来正常”的图其实插值到了错误的气压层。我当初第一次跑 72 小时批量出图时在 Windows 机器上连续装坏两个 conda 环境后来才意识到 1.1.3 的时代背景和与 cartopy 的绑定关系。现在团队里的新机器都固定成同一套 Python 3.8 加 conda-forge 安装流程这个库再没出过幺蛾子。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/28 5:58:01

UReport2 接入 Spring Boot:依赖、数据源、存储与排查实战

简介:面向Java开发者与报表开发初学者的UReport实践资料,围绕UReport2在Maven项目及Spring Boot环境中的接入方式展开,可帮助读者理解报表模板设计、数据源配置与PDF、Excel、Word等多格式报表生成流程。压缩包内共1个doc文件,约1…

2026/10/28 5:53:00

鸿蒙AI Native规模化交付:DevEco CLI作为交付契约中枢

1. 这不是一次简单的工具链升级:从“能跑”到“量产”的鸿蒙 AI Native 转折点高德地图团队在内部技术复盘会上,曾用一张对比图说明过去两年的鸿蒙适配路径:左边是2022年首批ArkTS模块上线时的截图——一个带定位图标、能加载基础瓦片、但交互…

2026/10/28 6:53:05

电容放电器原理与安全放电设计实战指南

1. 为什么一个几块钱的电容放电器,能救下整条手臂?电容放电器——这三个字听起来平平无奇,但在我拆修第7台报废变频器、第12台老式CRT显示器、第3台工业PLC电源模块时,它已经三次拦在我和“啪”一声炸响之间。不是夸张&#xff0c…

2026/10/28 6:53:05

QFN封装焊接全链路:焊盘钢网、回流曲线与空洞虚焊控制

QFN封装这两年在中小功率、中低引脚数的板子上几乎成了默认选项:电源管理、射频前端、传感器、MCU,随便翻一块四层板都能找出好几颗。但真正让硬件工程师头疼的从来不是"选不选QFN",而是"选完之后焊不焊得住"。我见过太多…

2026/10/28 6:53:05

小米手环数据自动化导出:定时备份云端健康数据到本地

简介:小米手环数据自动化导出工具,主要面向希望深入查看Zepp Life数据库、对个人健康数据进行归档或取证分析的折腾型用户。通过对Zepp Life软件进行解包,直接获取底层数据库,配合多个Python脚本完成备份提取、数据解析与重建&…

2026/10/28 6:53:05

MCP Manager Gateway:面向AI Agent的服务发现与按需调度中间件

1. 这不是“又一个网关”,而是 Agent 架构里被长期忽视的“服务发现层”你有没有遇到过这样的场景:写好了一个能调用天气 API 的 Skill,另一个同事写了数据库查询的 Skill,第三个同学封装了 PDF 解析的 Skill——大家各自为战&…

2026/10/28 6:53:05

ECC 全解析:从 P384 证书链到 SAP LSMW 数据迁移

ECC 这三个字母,在不同圈子里指向的东西完全不一样。做密码学的看到它想到的是椭圆曲线密码学(Elliptic Curve Cryptography),做企业信息化的看到它想到的是 SAP ERP Central Component,做汽车电子的看到它想到的是 En…

2026/10/28 6:48:04

后端工程师转型AI创作的技能迁移与实践指南

1. 项目概述最近在技术圈里有个现象特别有意思:越来越多的后端工程师开始尝试AI创作。作为一个在技术行业摸爬滚打多年的老码农,我也忍不住想聊聊这个话题。特别是看到脉脉上关于"技术人出路"的讨论越来越热,我觉得是时候做个实测&…

2026/10/27 14:24:03

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/27 9:34:54

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/28 0:02:13

Python股票自动交易系统源码解析:从行情获取到风控的完整链路

简介:这份资源是面向高校计算机、金融相关专业毕业设计场景的完整项目源码包,主题为基于Python的股票自动交易系统,适合需要完成毕设选题、课程设计或自学金融量化交易开发的学生与开发者参考。压缩包共收录687个文件,整体约14.93…

2026/10/28 0:02:13

视酷酷信IM源码部署指南:Java 17+MySQL 8.0.33实战配置

简介:这是一套2024年亲测可部署的视酷酷信IM即时通讯系统源码,面向具备Java、OC、C#及Vue开发能力的技术人员,解决私有化即时通讯平台快速搭建与二次定制需求,尤其适用于需集成商城、保障数据主权的中小型企业或独立开发者。资源共…

2026/10/28 0:02:13

Python爬取百度迁徙数据:接口解析、批量采集与避坑指南

简介:这份资源是一个用Python爬取百度迁徙数据的脚本压缩包,面向具备Python基础、希望入门网络爬虫与数据解析的开发者,解决按日期获取全国热门城市人口迁徙数据的问题。包内共1个文件,为单个py脚本,压缩包约1KB&#…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑