如何仅绘制雷达数据的特定区域网格?
问题排查与修复方案
你的代码存在三个核心问题:坐标转换顺序错误导致掩码数组异常、多边形尺寸计算逻辑错误、颜色赋值逻辑漏洞,以下是针对性修复:
1. 修复掩码数组形状异常
你提到掩码后得到(4058,0)的异常形状,根源是坐标转换时的输出顺序错误,且双重循环容易引发索引偏差:
- 多数CRS转换器的转换逻辑是**(x, y) → (lon, lat)**,你代码中
lat, lon = transformer.transform(...)颠倒了经纬度,导致后续边界判断完全失效,大量有效点被误标为NaN。 - 替换低效的双重循环为矢量转换,避免索引错误:
# 替换原坐标转换的双重循环 # 将二维网格转为一维点集 points = np.column_stack((x_grid.ravel(), y_grid.ravel())) # 批量转换坐标(根据你的transformer确认输出顺序,这里假设是lon, lat) lons, lats = transformer.transform(points[:, 0], points[:, 1]) # 重塑为原网格形状 lon_grid = lons.reshape(x_grid.shape) lat_grid = lats.reshape(y_grid.shape) # 矢量化边界判断生成掩码 mask = (lon_grid >= lboundary) & (lon_grid <= rboundary) & \ (lat_grid >= bboundary) & (lat_grid <= tboundary) # 对无效区域赋值NaN lon_grid[~mask] = np.nan lat_grid[~mask] = np.nan # 重新生成掩码后的数组 masked_lon_grid = lon_grid[mask] masked_lat_grid = lat_grid[mask] masked_var = var[mask] # 此时形状应为(4058,),而非(4058,0) print(masked_var.shape)
2. 修复多边形生成逻辑
原代码通过masked_lon_grid[1]-masked_lon_grid[0]计算网格宽度完全错误——掩码后的一维数组是行优先展开的,相邻元素在地理上并不连续,导致生成的多边形尺寸完全偏离实际:
- 改用原始metric网格的间距计算单元尺寸,再批量转换为经纬度角点:
# 计算原始metric网格的单元步长 x_step = x[1] - x[0] y_step = y[1] - y[0] # 获取有效点的metric坐标 x_valid = x_grid[mask] y_valid = y_grid[mask] # 计算每个网格单元的四个metric角点 x0 = x_valid - x_step/2 x1 = x_valid + x_step/2 y0 = y_valid - y_step/2 y1 = y_valid + y_step/2 # 批量转换四个角点的经纬度 lon_tl, lat_tl = transformer.transform(x0, y1) # 左上 lon_tr, lat_tr = transformer.transform(x1, y1) # 右上 lon_br, lat_br = transformer.transform(x1, y0) # 右下 lon_bl, lat_bl = transformer.transform(x0, y0) # 左下 # 构造多边形数组(按顺时针顺序) polygones = np.stack([[lon_tl, lat_tl], [lon_tr, lat_tr], [lon_br, lat_br], [lon_bl, lat_bl]], axis=1).astype(np.float32)
3. 修复颜色赋值与显示问题
区域显示为蓝色,要么是colors未正确初始化,要么是levels未覆盖masked_var的数值范围:
- 先初始化符合要求的颜色数组:
# 初始化RGBA格式的颜色数组,形状与masked_var一致 colors = np.zeros((masked_var.shape[0], 4))
- 优化区间匹配逻辑,避免漏判最大值:
sum_polygones = [] for m in range(ncol): # 最后一个区间包含等于最大值的情况 if m == ncol - 1: var_mask = (masked_var >= levels[m]) else: var_mask = (masked_var >= levels[m]) & (masked_var < levels[m+1]) # 为匹配的单元赋值颜色 colors[var_mask] = cmap(m) sum_polygones.append(np.sum(var_mask)) # 检查数值范围是否匹配 print(f"masked_var数值范围: {masked_var.min()} ~ {masked_var.max()}") print(f"levels区间范围: {levels.min()} ~ {levels.max()}")
4. 坐标系一致性检查
确保PolyCollection的转换坐标系与地图轴的投影一致:
# 示例:创建PlateCarree投影的轴 ax = plt.axes(projection=ccrs.PlateCarree()) # 使用与轴一致的转换坐标系 poly_collection = PolyCollection(polygones, edgecolors='black', facecolors=colors, linewidth=.5, transform=ccrs.PlateCarree()) ax.add_collection(poly_collection) # 适配目标区域范围 ax.set_extent([lboundary, rboundary, bboundary, tboundary], crs=ccrs.PlateCarree())
内容的提问来源于stack exchange,提问作者Louschmuh
相关产品推荐
相关产品推荐

