如何将印度区域外数据设为NaN?使用mask函数遇类型错误
问题解决:印度区域外数据设为NaN及mask函数报错处理
问题概述
- 需求:仅可视化印度区域内的降水数据,将区域外数值设为NaN
- 现存问题:
- 仅设置绘图范围后,区域外数据仍会显示
- 使用mask函数时触发
TypeError: 'NoneType' object is not iterable,移除含None的id列后错误未解决
解决方案
核心思路
先通过地理边界对原始数据进行掩码处理,而非仅依赖绘图范围限制;同时排查shapefile读取及数据缺失问题,解决mask函数报错。
步骤1:导入额外依赖库
需要用到shapely处理地理几何判断,numpy处理数组掩码:
import numpy as np from shapely.geometry import Point from shapely.geometry.polygon import Polygon
步骤2:读取印度边界并创建掩码
# 读取shapefile shp = r'C:\Users\IMD\Swapi\india polygon\india-polygon.shp' reader = shapereader.Reader(shp) geometries = list(reader.geometries()) # 检查几何图形是否读取成功 if not geometries: raise ValueError("Shapefile未读取到有效几何图形,请检查路径或文件完整性") india_polygon = geometries[0] # 生成经纬度网格 lon, lat = np.meshgrid(tp.longitude, tp.latitude) # 创建掩码:区域外的点标记为True(对应设为NaN) mask = np.array([[not india_polygon.contains(Point(lon[i,j], lat[i,j])) for j in range(lon.shape[1])] for i in range(lon.shape[0])]) # 应用掩码到数据 masked_tprate = np.where(mask, np.nan, tp.tprate[0,:,:]*1000)
步骤3:用掩码后的数据绘图
替换原contourf中的数据参数,其余绘图代码保持不变:
vp_fill = plt.contourf(tp.longitude, tp.latitude, masked_tprate, clevs, transform=ccrs.PlateCarree(), cmap=plt.cm.viridis_r, extend='both')
报错排查要点
如果仍出现NoneType相关错误:
- 确认shapefile路径正确,文件未损坏:可以尝试用GIS软件打开shapefile验证
- 检查数据的经纬度是否有缺失值:
若存在缺失值,先清理数据:print("经度缺失值:", tp.longitude.isnull().any().item()) print("纬度缺失值:", tp.latitude.isnull().any().item())tp = tp.dropna(dim='longitude').dropna(dim='latitude')
完整修正代码
import matplotlib.pyplot as plt import cartopy.crs as ccrs from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter from cartopy.io import shapereader import numpy as np from shapely.geometry import Point from shapely.geometry.polygon import Polygon plt.rcParams["figure.figsize"] = (12, 10) ax = plt.axes(projection=ccrs.PlateCarree()) clevs = [0, 0.05, 0.1, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60] # 读取印度边界并创建掩码 shp = r'C:\Users\IMD\Swapi\india polygon\india-polygon.shp' reader = shapereader.Reader(shp) geometries = list(reader.geometries()) if not geometries: raise ValueError("Shapefile未读取到有效几何图形,请检查路径或文件完整性") india_polygon = geometries[0] # 生成网格并创建掩码 lon, lat = np.meshgrid(tp.longitude, tp.latitude) mask = np.array([[not india_polygon.contains(Point(lon[i,j], lat[i,j])) for j in range(lon.shape[1])] for i in range(lon.shape[0])]) masked_tprate = np.where(mask, np.nan, tp.tprate[0,:,:]*1000) # 绘制掩码后的数据 vp_fill = plt.contourf(tp.longitude, tp.latitude, masked_tprate, clevs, transform=ccrs.PlateCarree(), cmap=plt.cm.viridis_r, extend='both') cbar = plt.colorbar(vp_fill, orientation='vertical') cbar.ax.tick_params(labelsize=14) # 设置印度区域的刻度和范围 ax.set_xticks([70, 75, 80, 85, 90, 95, 100], crs=ccrs.PlateCarree()) ax.set_yticks([5, 10, 15, 20, 25, 30, 35], crs=ccrs.PlateCarree()) ax.set_extent([68, 100, 5, 35]) ax.coastlines(alpha=0.8) # 添加邦界 ax.add_geometries(geometries, ccrs.PlateCarree(), edgecolor='k', facecolor='none') plt.show()
内容的提问来源于stack exchange,提问作者Swapnil Kori
相关产品推荐
相关产品推荐

