☰
Python绘制多普勒雷达PPI强度图:基数据读取与极坐标显示全解析
2026/10/26 8:30:50 网站建设 项目流程

简介:面向多普勒雷达强度数据显示与分析的处理演示包,专门用来解析敏视达气象雷达回波强度数据,适合气象专业学生、雷达数据研究人员及需要了解雷达基数据格式与可视化流程的开发者。压缩包为rar格式,共13个文件,体积约737KB,主要包含dat雷达回波数据文件、exe可执行程序,以及Visual C++工程配套的dsw/dsp、pdb/ncb等编译调试辅助文件,既可用于数据浏览,也可作为源码研读的起点。已有258人学习/下载。程序通过读取dat数据完成距离换算、多普勒速度计算与强度分析,并基于回波往返时间与多普勒频移原理,输出彩色降水回波图像,方便对照多组示例数据反复验证结果。对于入门气象雷达信号处理或进行程序二次开发的读者,这是一份轻量而完整的参考样例。

1. 气象雷达回波强度显示的最后一公里:ShowRadarData 在解决什么

拿到一个多普勒雷达基数据文件,最常见的诉求不是去做定量估测,而是先把回波强度画出来看一眼:这团回波有多强、往哪个方向移、哪块区域可能已经到中气旋的强度门槛。ShowRadarData_intensity 这类命名,背后对应的就是气象雷达数据处理里最日常的一步——把基数据里的反射率强度提出来,转成一张能看的平面显示图。这里要补一句:气象雷达平面显示 PPI(Plan Position Indicator)指的就是把极坐标扫描的结果按方位角和距离库画成一张二维回波强度图,这是所有后续产品的基础。本文面向的读者是刚接触气象雷达基数据的科研助手、临近预报开发者和雷达算法验证工程师,目标是让你不依赖商业软件,也能用开源工具自己把强度数据从文件里读出来、画成 PPI、再根据业务需求把参数调对。

2. 读懂多普勒雷达基数据:从径向扫描到 PPI 强度图

2.1 体积扫描与径向:气象雷达数据的基本单位

多普勒气象雷达的观测方式不是直接给出一张二维图片,而是通过体积扫描(VCP,Volume Coverage Pattern)完成的。雷达天线在一个固定仰角上围绕站点做 360 度旋转,每转一圈,得到一个仰角层的扫描数据;然后天线抬升到下一个仰角继续旋转。一次完整体扫通常包含 9 到 14 个仰角层,低层仰角间隔密、高层间隔疏,这是为了在低层获取更精细的降水结构。

每一圈扫描由若干根径向(ray)组成。径向是雷达在某一固定方位角上向外发射电磁波脉冲后,按距离库(range gate)顺序采样得到的一串回波强度值。距离库的长度取决于脉冲宽度和采样频率,常见配置是 125 米、250 米或 1000 米。也就是说,一个体扫文件里的数据结构大致是:体扫 -> 仰角层 -> 径向 -> 距离库。把任意一根径向拉出来,横轴是距离库,纵轴是回波强度,就是一条典型的距离-强度剖面;把所有径向按方位角顺序排列,就得到一个二维极坐标矩阵。

理解这层结构对后续编程很重要,因为很多新手上手时直接按经纬度网格的思路去读文件,结果发现数据维度是(径向数,距离库数)而不是(行,列)。只要记住雷达数据从生成那一刻起就是极坐标的,文件里的组织结构自然就好理解了。

2.2 PPI 平面显示:为什么是极坐标而不是经纬度网格

PPI(Plan Position Indicator)是气象雷达平面显示的标准产品形态。在 PPI 图上,雷达站点位于中心,方位角从正北开始沿顺时针方向增加,距离从中心向外辐射,等距离半径圈对应距离库的位置。这个坐标系直接继承自雷达的扫描方式,所以 PPI 本质上就是把极坐标矩阵用等距方位投影画到平面上。

很多人第一次接触雷达数据会问:为什么不能直接把回波强度当成普通图片的像素去显示?原因是雷达的角分辨率随距离变化,靠近站点的相邻方位角之间间距小,远距离处同样 1 度方位角对应的弧长可能达到几公里。如果直接把原始矩阵拉伸成矩形图像,近距离回波会被严重拉伸变形,远距离回波会变得过密。PPI 显示必须把每个距离库按实际地理位置摆放到图上,也就是做一次极坐标到直角坐标的映射。

这里有一个容易被忽略的约定:气象雷达的方位角是从正北起算、顺时针旋转,这和数学上常用的从正东起算、逆时针旋转不同。在把极坐标转换到屏幕坐标时,角度起点和旋转方向必须和文件里的方位角定义保持一致,否则画出来的回波位置会整体镜像或旋转 90 度,这在第 5 章会专门讲。

2.3 反射率因子 Z 与 dBZ:强度数据在文件里怎么存

回波强度的物理量是反射率因子 Z,单位是 mm^6/m^3,但实际业务中几乎都用 dBZ(即 10*lg10(Z))表示。dBZ 的动态范围很大,弱层状云回波通常在 -10 到 10 dBZ,普通降水在 20 到 40 dBZ,强对流核心可以超过 60 dBZ。文件里存储的字段名通常是 reflectivity 或 DBZH,这取决于雷达数据处理软件的约定。

注意:不是所有文件里的反射率字段都直接存成 dBZ 浮点数。很多原始基数据为了压缩体积,会用整数存储,并附带 scale_factor 和 add_offset 两个元数据,真实 dBZ 值通过 raw * scale_factor + add_offset 还原。读取数据后第一件事就是检查字段属性,如果直接拿原始整数去绘图,颜色映射会完全错乱。另有两类特殊值需要处理:一类是缺测值,表示该距离库没有有效回波,常见标记是 NaN 或极大整数;另一类是无效值,表示雷达在近距离盲区或远距离杂波区域。这两类值如果不加区分地参与绘图,会在图上形成诡异的条纹或色斑。

2.4 从极坐标到屏幕坐标:一张 PPI 是怎么画出来的

把极坐标矩阵映射到平面图的核心公式很简单。设某根径向的方位角为 θ(单位弧度),某个距离库的距离为 r(单位米),该点在平面上的位置是:

x = r * sin(θ) y = r * cos(θ)

公式本身不难,但有两个细节决定了效果。第一,θ 使用文件里的方位角值,而不是重新按角度生成的序列,因为雷达扫描过程中径向的方位角并不是严格等间隔的;第二,在 Python 里用 meshgrid 生成网格时,维度的顺序必须和反射率矩阵的维度对齐,否则画出来就是错位的。把这个变换做对,再用 pcolormesh 或 imshow 把 dBZ 数值映射成颜色,一张最基础的 PPI 强度图就出来了。

3. 用 Python 复刻 ShowRadarData 的取数流程:从基数据到可运行脚本

3.1 准备:搭建环境与目录结构

复刻这类取数显示脚本的首选工具是 Py-ART 加 NumPy 加 Matplotlib。Py-ART 负责读取基数据文件,NumPy 负责极坐标变换和数组操作,Matplotlib 负责绘图。Wradlib 也可以实现同样功能,但 Py-ART 在读取 CF-Radial、ODIM_H5 等气象雷达标准格式时字段映射更省心,我一般先用 Py-ART 跑通流程。

radar_project/ ├── data/ # 放基数据文件 │ └── 20240815_0600_radar.nc ├── scripts/ │ ├── read_radar.py │ ├── plot_ppi.py │ └── utils.py └── output/ └── ppi/

环境安装注意一点:Py-ART 对底层二进制依赖较多,建议用 conda 创建独立环境,直接 pip install 有时会编译报错。装完依赖后先跑一句python -c "import pyart; print(pyart.__version__)"验证环境可用,再继续。

3.2 读取基数据并列出可用仰角

第一步是把文件读进来,看看里面有多少仰角层、每层对应多少根径向、距离库数是多少。

import pyart # 读取雷达基数据文件,Py-ART 会自动识别格式 radar = pyart.io.read("data/20240815_0600_radar.nc") # 列出所有扫描层的仰角值 print("固定仰角:", radar.fixed_angle["data"]) print("扫描层数:", radar.nsweeps) # 查看基础尺寸信息 for i in range(radar.nsweeps): nrays = radar.get_ray_count(i) # 第 i 层的径向数 nrange = radar.range["data"].shape[0] # 距离库数 print(f"扫描层 {i}: 仰角 {radar.fixed_angle['data'][i]:.1f}°, " f"径向 {nrays}, 距离库 {nrange}")

Py-ART 的 read 函数会自动识别常见的雷达基数据格式,包括 CF-Radial、NEXRAD Level II、SIGMET 等。fixed_angle 数组存储的是每个扫描层的名义仰角,但实际每一根径向的仰角可能存在微小偏差,所以业务上通常用 fixed_angle 来选层。radar.nsweeps 表示体扫包含的层数,get_ray_count 返回指定层的径向数量,正常情况下应该接近 360 个左右。

如果打印出来的仰角范围和预期不符,比如全部是负值或者没有 0.5 度层,先检查文件本身是否经过了裁剪或只包含部分体扫。还有一种情况是文件里除了反射率还有多普勒速度和谱宽字段,这些不影响读取,但后面取数据时要明确指定字段名。

3.3 抽取指定仰角的反射率强度并还原 dBZ

选一个低仰角层(通常取 0.5 度或 1 度,降水观测最常用),把该层的反射率字段取出来,并检查是否有需要还原的量程变换。

import numpy as np # 取第 0 个扫描层(通常是低层) sweep = 0 reflectivity = radar.get_field(sweep, "reflectivity") # 查看数据范围和字段元数据 print("数据形状:", reflectivity.shape) print("原始最小值:", np.nanmin(reflectivity)) print("原始最大值:", np.nanmax(reflectivity)) # 某些文件存的是缩放后的整数,需要按元数据还原 if hasattr(reflectivity, "get_metadata"): meta = reflectivity.get_metadata() scale = meta.get("scale_factor", 1.0) offset = meta.get("add_offset", 0.0) if scale != 1.0 or offset != 0.0: reflectivity = reflectivity * scale + offset print("已按 scale_factor 和 add_offset 还原 dBZ")

Py-ART 在加载标准 C 波段的 CF-Radial 文件时,一般已经把单位转成 dBZ 了,但许多国产雷达基数据或经过自定义处理的文件仍然保留整数存储,这时元数据里的 scale_factor 和 add_offset 就是唯一还原依据。另外,反射率字段本身可能是一个 masked array,掩码标记了缺测位置,直接用 np.nanmin 会得出的结果可能无效。

检查完单位后,把缺测值统一处理成 NaN,这样后续绘图时 Matplotlib 会把这些位置留白,而不是当成 0 值参与映射。

3.4 极坐标转直角坐标:生成 PPI 画布

提取出反射率矩阵后,把方位角和距离库转成二维网格坐标,再用 pcolormesh 绘制。

import matplotlib.pyplot as plt # 取出距离库和方位角的一维数组 r = radar.range["data"] # 距离库,单位米 az = radar.azimuth["data"] # 方位角,单位度 az_rad = np.deg2rad(az) # 转弧度 # 生成二维网格:r 沿第一维,方位角沿第二维 azi_grid, r_grid = np.meshgrid(az_rad, r) # 极坐标到平面坐标 x = r_grid * np.sin(azi_grid) y = r_grid * np.cos(azi_grid) # 反射率矩阵转置成(距离库,方位角)布局,与网格对齐 ref_2d = np.array(reflectivity).T fig, ax = plt.subplots(figsize=(8, 8)) mesh = ax.pcolormesh(x, y, ref_2d, shading="nearest", cmap="turbo", vmin=-10, vmax=60) plt.colorbar(mesh, ax=ax, label="dBZ") ax.set_aspect("equal") ax.set_xlabel("东向距离 (m)") ax.set_ylabel("北向距离 (m)") plt.savefig("output/ppi_0.5deg.png", dpi=150)

这里的关键点是网格布局。np.meshgrid 默认生成的数组第一维长度对应第一个参数的长度,第二维对应第二个参数的长度。r 有 N 个元素,az 有 M 个元素,则 x、y 的形状是 (N, M),而反射率原始矩阵的形状是 (M, N)(M 根径向,每根 N 个距离库),所以要转置一次才能与网格对齐。这个顺序错一个,画面就会沿对角线错位。

shading="nearest" 表示把每个点的坐标当成网格中心而不是网格角点,可以避免 pcolormesh 在数据点排列不严格规则时报错或画出不连续的边缘。vmin 和 vmax 控制颜色映射量程,不要直接使用默认值,否则数据里偶尔出现的异常值会把整个色带拉伸失效。如果看到图上有大量空白区域,第一反应是检查雷达有效探测半径和距离库范围,而不是急着调色标。

3.5 封装函数:把流程固定下来

把前面几步封装成函数,方便对多个文件批量出图,这是实际工作中最常用的形态。

def plot_ppi_intensity(radar, sweep_index=0, output_path=None, vmin=-10, vmax=60): """ 从雷达基数据对象绘制指定仰角的PPI强度图 """ reflectivity = radar.get_field(sweep_index, "reflectivity") r = radar.range["data"] az_rad = np.deg2rad(radar.azimuth["data"]) # 统一缺测为 NaN ref = np.array(reflectivity, dtype=float) if np.ma.is_masked(reflectivity): ref[reflectivity.mask] = np.nan azi_grid, r_grid = np.meshgrid(az_rad, r) x = r_grid * np.sin(azi_grid) y = r_grid * np.cos(azi_grid) fig, ax = plt.subplots(figsize=(9, 9)) mesh = ax.pcolormesh(x, y, ref.T, shading="nearest", cmap="turbo", vmin=vmin, vmax=vmax) plt.colorbar(mesh, ax=ax, label="dBZ") ax.set_aspect("equal") ax.set_title(f"PPI {radar.fixed_angle['data'][sweep_index]:.1f} deg") if output_path: plt.savefig(output_path, dpi=150, bbox_inches="tight") else: plt.show()

封装后的函数接受一个体扫对象,指定仰角层序号和输出路径即可出图。我建议把 vmin=-10、vmax=60 作为默认值,这是层状云到强对流都覆盖的常规量程;如果业务关注弱回波,再把 vmin 降到 -15 或 -20。注意函数里对 masked_array 的特殊处理:np.array 转换后掩码信息会丢,必须先取 mask 再赋 NaN,否则画图时缺测区可能显示为 0 dBZ 的蓝色。

4. PPI 显示参数怎么定:dBZ 量程、平滑窗口与缺测值处理的取舍

4.1 dBZ 量程与色标:按业务规范选还是按数据自适应

PPI 颜色映射的表象是配色问题,本质是气象业务规范问题。预报员看习惯了蓝绿黄橙红紫的分档色标,突然给一张 turbo 连续色带的图,强度判读会慢半拍。我自己做显示工具时,默认采用分级色标,把 dBZ 分成 7 到 8 档,每档绑定固定颜色,再用 BoundaryNorm 控制映射边界。

from matplotlib.colors import BoundaryNorm, ListedColormap # 定义颜色分档,常规业务色标 levels = [-25, 5, 15, 25, 35, 45, 55, 65] colors = ["#a0c8f0", "#00e0e0", "#00e000", "#e0e000", "#e08000", "#e00000", "#c000c0"] cmap_pp = ListedColormap(colors) norm_pp = BoundaryNorm(levels, cmap_pp.N) # 绘图时替换 cmap 和 norm # mesh = ax.pcolormesh(x, y, ref.T, shading="nearest", cmap=cmap_pp, norm=norm_pp)

量程选择上,层状云降水场景把下限设到 -10 dBZ 就够了;监测弱降雪或雾,需要把下限放到 -25 dBZ,否则弱回波会被色标压成一片白。上限设到 65 dBZ 对绝大多数对流有效,但做冰雹识别时上限留到 70 更安全。这里的取舍原则是宁可让极少数强回波溢出,也不能让中间阈值分不清。

还有一点容易被忽略:BoundaryNorm 适合等距分档,如果想让弱回波层显示更细腻,可以把 0 到 20 dBZ 之间的间隔加密到 2.5 dBZ。Matplotlib 的色标分档完全由 levels 数组控制,不需要改绘图逻辑,这是分级色标优于连续色带的地方。

4.2 距离库与网格分辨率:多少像素才够用

PPI 显示分辨率的调节有两个层面:一是雷达本身的距离库长度,二是你转成直角坐标后用的网格像素数。前者是数据固有的,250 米距离库对应最大探测半径 250 公里时就有 1000 个点;后者决定了画布尺寸。

如果你的目标是出图不超过 1500 像素宽,直接用 pcolormesh 映射最省事,把每个距离库当作一个小色块,不需要重采样。但如果要做动画切片或叠加精细底图,就得做一次规则网格重采样,把极坐标数据插值到等间距直角网格。做法是先建立目标网格,再用 scipy.interpolate.griddata 做插值,网格间距常见设为距离库长度的两倍,即 250 米数据的网格间距取 500 米,能有效避免插值空洞。网格太密时计算量会指数上升,而回波结构并不会变清晰,因为原始数据的分辨率上限就在那里。

这里提一个常见的“虚假高分辨率”问题:源数据只有 250 米距离库分辨率,你强行插值到 50 米网格,画面上确实平滑了,但会制造出不存在的小尺度结构。显示产品可以这样做,但做定量算法验证时一定不要用重采样后的数据去提取回波参数,否则结果是不可信的。

4.3 径向平滑:杂波抑制和滤波窗口的取舍

雷达回波强度图在展示前通常要做一道平滑,目的是压掉孤立杂点和波束之间的不连续。最简单有效的做法是在极坐标域做滑窗中值滤波,窗口沿方位角方向和距离库方向分别设置。

from scipy.ndimage import median_filter # 先把 NaN 填补成一个远离有效范围的数,滤波后再还原 ref_filled = np.where(np.isnan(ref), -999.0, ref) ref_sm = median_filter(ref_filled, size=(3, 5), mode="nearest") # 将有回波但滤波后变成非正常值的点还原为 NaN ref_sm[ref_filled == -999.0] = np.nan

size 的取值逻辑是:第一个维度是方位角方向,取奇数 3 或 5,因为雷达径向扫描时相邻径向之间的回波连续性较强,取 3 即可;第二个维度是距离库方向,取 5 或 7,距离方向通常有沿程衰减和杂散点,需要更大窗口压平。窗口参数不是越大越好,取到 9 以上会把弱回波边缘磨平,形成一种圆润的块状感。

还有一个实际手段:零阶质量控制在显示前做一道杂波阈值滤除,对反射率低于 5 dBZ 且空间孤立(相邻距离库无有效值)的点直接置 NaN。这比单纯平滑效果更自然,但也可能误杀弱降水边缘,阈值取多少需要对照你所在地区的降水气候态反复试,我通常从 0 dBZ 起步调试,这部分确实是经验活,有点玄学成分。

4.4 显示范围与坐标系统:中心点怎么选

业务显示上还要决定一个参数:PPI 图的显示范围是跟随雷达最大探测距离,还是截取某个固定半径。最大探测距离通常到 230 公里或 250 公里,但远距离处波束中心高度已经超过 10 公里,看到的回波是高层云的空腔,对中低层降水分析没有意义。

常见做法是把显示范围限制在 150 公里内。要改这个参数,不需要改动重采样代码,只需要在绘图时约束 x 和 y 的坐标范围:

ax.set_xlim(-150_000, 150_000) ax.set_ylim(-150_000, 150_000)

如果之后要叠加行政区划、河流、高速公路底图,建议把直角坐标原点定在雷达站点经纬度,而不是直接画(0,0)中心。把基数据的 radar.latitude、radar.longitude 传给 Cartopy 的 GeoAxes,可以把回波准确地画在地图上。

5. PPI 显示异常排查:方位角镜像、全黑底图与强度错位

5.1 方位角起算不一致导致上下镜像

现象:画出的回波位置与真实地理方位上下颠倒,比如雷达西北方向的回波显示到了西南方向,整张图看起来像做了一次左右或上下翻转。

原因:气象雷达的方位角起点是正北,方向是顺时针,但部分数据文件或开源工具内部遵循数学坐标系约定,以正东为起点逆时针旋转。坐标变换公式中直接用 sin 和 cos 计算 x、y 时,会把方位角当成数学角度处理,一旦文件里的方位角实际是气象约定,成图就会镜像。

解决:先确认数据源的角度约定。读取任意一根径向的 azimuth 值,对比该径向对应的回波位置是否合理;如果确认文件是气象约定而绘图结果镜像,将 y 坐标公式改为y = -r_grid * np.cos(azi_grid),或在转换前对方位角做az_fixed = (90 - az) % 360变换。注意改公式前先验证一根径向的方向,不要盲改。

5.2 原始整数没还原,整幅图强度失真

现象:PPI 图上所有回波都偏小或偏大,比如明明是 35 dBZ 的降水核心,图上显示成 8 或 9,色标量程怎么调都对不上。

原因:文件里反射率存储为整型,真实值必须经过 scale_factor 和 add_offset 换算,直接读取整数画图,量程错位是必然的。另一种类似情况是字段里正好存了反射率因子 Z(mm^6/m^3),而不是 dBZ,这时数值范围从几十万到上亿,色标完全失去意义。

解决:读取字段后先检查单位属性。单位如果是 dBZ 正常使用;如果是 mm^6/m^3,先做ref_dbz = 10 * np.log10(ref_z)转换。如果数据已被处理成 int16 原始值,按元数据里的 scale_factor 和 add_offset 手动还原。检测手段很简单:打印几分钟数据的统计值,超过 80 或为负数时就要怀疑单位没对。

5.3 缺测值填了 0,回波图变成满屏红

现象:PPI 图上原本应该空白的区域变成大幅连续红色块或蓝色块,看起来像暴雨覆盖整个雷达探测范围。

原因:缺测值在数据处理时被当作常规数值参与运算。最典型的是用 np.nan_to_num 将 NaN 填成了 0,在色标映射中 0 dBZ 对应蓝绿色,于是无回波区域变成了弱回波区域;如果原始文件里缺测值被标为 0,且绘图色标下限也为 0,就会看到满屏同类颜色。

解决:先从源头保证缺测值为 NaN,绘图前额外加一道检查:如果输入数组的 NaN 比例超过预期(比如超过 30%),暂停绘图打印诊断信息。还有一个更隐蔽的情况:布尔掩码数组在转 float 时掩码信息会丢,所以处理 masked array 时要像 3.5 节那样显式取 mask 赋 NaN。

5.4 径向条纹和扇形锯齿:重采样分辨率不够

现象:画出来的 PPI 回波边缘呈锯齿状,强回波区域能明显看到一根根径向条纹,尤其在远距离处,相邻径向之间出现亮暗交替。

原因:雷达扫描本身是逐径向采样,高仰角层或稀疏扫描模式下径向之间夹角大,加上方位角上不做插值,直接映射到直角坐标时,远距离处的径向间距远大于像素尺寸,就会出现扇形的“扇贝”纹路。

解决:在极坐标域对方位角补插值。常见参数是每根径向之间线性插入 3 到 4 个虚拟径向,再重新生成网格。另一个方向是适当调低显示上限,例如把最大距离从 230 公里截到 150 公里,扇形效应会明显缓解。做体扫动画时还要注意径向数不稳定问题,不同扫描层径向数量可能不同,逐帧读取时不要假设每一帧都是 360 根径向。

5.5 体扫动画帧与帧之间坐标轴跳变

现象:连续多帧 PPI 图合成为动图时,回波位置在跳动,底图一帧偏左一帧偏右,回波强度看起来也在忽大忽小。

原因:每一帧绘图时坐标范围由该帧数据的最大值自动决定,而体扫中不同时刻的低层扫描范围或距离库数可能不同,导致坐标轴范围逐帧变化;另外如果每帧都单独调用一次 set_xlim 而不固定,就会产生跳变。

解决:在动画循环外固定 x、y 坐标范围,用所有帧的统一探测范围一次性设定ax.set_xlim和ax.set_ylim。颜色映射的 vmin/vmax 也一并固定,不要依赖每帧数据自动缩放。这点不处理好,动图看起来就会忽明忽暗,数据没问题也会被误判为雷达故障。

6. 进阶验证技巧:把单帧 PPI 变成方位切片与强度剖面

只出一张矩形 PPI 图,很多时候并不能验证数据的真实性。我的习惯是画完图后立刻叠加一个方位切片,固定一个方位角,把该角度上所有距离库的强度拉成一条曲线,看看从近到远的回波变化是否符合降水结构。这一步能把静态图变成可交互检核的工具。

def plot_azimuth_slice(radar, sweep_index=0, azimuth_angle=210.0): ref = radar.get_field(sweep_index, "reflectivity") az = radar.azimuth["data"] r = radar.range["data"] # 找到与目标方位角最接近的径向索引,考虑角度环绕 diff = np.abs((az - azimuth_angle + 180) % 360 - 180) ray_idx = int(np.argmin(diff)) fig, ax = plt.subplots(figsize=(10, 4)) ax.plot(r / 1000.0, ref[ray_idx], "b-", linewidth=1.2) ax.set_xlabel("距离 (km)") ax.set_ylabel("反射率 (dBZ)") ax.set_ylim(-10, 65) ax.grid(True, linestyle="--", alpha=0.5) ax.set_title(f"方位角 {az[ray_idx]:.1f} 度强度剖面")

这段代码先计算目标方位角与所有径向的夹角差,利用取模运算处理方位角跨越 0 度和 360 度的情况,再取出对应径向的数据绘图。用距离剖面可以快速确认雷达径向数据是否连续、地物杂波出现在哪个距离段、强回波核高度结构是否合理。我拿到一套新雷达数据源,第一件事永远是先看方位角起点和缺测标记,确认了再画图,这个习惯帮我排掉了相当一部分外部数据源的暗坑。希望帮到你。

本文还有配套的精品资源,点击获取

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

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

立即咨询