特定偏移Transverse Mercator投影下NaturalEarthFeature显示异常求助
解决Transverse Mercator投影下LAND要素异常全灰问题
问题根源
你犯了Cartopy使用里的典型错误:add_feature时指定的transform参数完全错了。Natural Earth的LAND、COASTLINE这类要素,默认都是基于WGS84经纬度坐标系(也就是ccrs.PlateCarree())存储的,你却把transform设成了用来显示的Transverse Mercator投影,坐标系转换逻辑直接乱掉,才会出现全灰覆盖的异常。
修正后的代码
全局范围(中央经度10)
import cartopy.crs as ccrs import cartopy.feature as feature import matplotlib.pyplot as plt fig1 = plt.figure() display_crs = ccrs.TransverseMercator(central_longitude=10) ax = fig1.add_subplot(projection=display_crs) ax.set_global() # 关键:transform要用要素原始的PlateCarree坐标系 ax.add_feature(feature.LAND, transform=ccrs.PlateCarree()) ax.add_feature(feature.COASTLINE, transform=ccrs.PlateCarree()) plt.show()
北欧区域范围
import cartopy.crs as ccrs import cartopy.feature as feature import matplotlib.pyplot as plt fig1 = plt.figure() display_crs = ccrs.TransverseMercator(central_longitude=10) ax = fig1.add_subplot(projection=display_crs) ax.set_extent([2, 30, 54, 72], crs=ccrs.PlateCarree()) # 同样,transform保持PlateCarree ax.add_feature(feature.LAND, transform=ccrs.PlateCarree()) ax.add_feature(feature.COASTLINE, transform=ccrs.PlateCarree()) plt.show()
额外:限制LAND要素绘制范围的方法
如果想进一步只渲染特定区域的陆地,有两种实用方法:
方法1:加载指定区域的Natural Earth子要素
Natural Earth提供分区域的Shapefile,比如只加载欧洲陆地:
import cartopy.crs as ccrs import cartopy.feature as cfeature from cartopy.io.shapereader import Reader import matplotlib.pyplot as plt fig, ax = plt.subplots(subplot_kw={'projection': ccrs.TransverseMercator(central_longitude=10)}) ax.set_extent([2, 30, 54, 72], crs=ccrs.PlateCarree()) # 加载本地的欧洲陆地Shapefile(需提前下载Natural Earth 1:110m尺度的陆地文件) europe_land = cfeature.ShapelyFeature( Reader('ne_110m_land/ne_110m_land.shp').geometries(), ccrs.PlateCarree(), facecolor=cfeature.COLORS['land'] ) ax.add_feature(europe_land) ax.add_feature(cfeature.COASTLINE, transform=ccrs.PlateCarree()) plt.show()
方法2:用路径裁剪全局LAND要素
直接对全局陆地要素做范围裁剪,不用额外下载文件:
import cartopy.crs as ccrs import cartopy.feature as cfeature import matplotlib.pyplot as plt from matplotlib.path import Path fig, ax = plt.subplots(subplot_kw={'projection': ccrs.TransverseMercator(central_longitude=10)}) extent = [2, 30, 54, 72] ax.set_extent(extent, crs=ccrs.PlateCarree()) # 生成对应经纬度范围的裁剪路径 clip_path = Path([ (extent[0], extent[2]), (extent[1], extent[2]), (extent[1], extent[3]), (extent[0], extent[3]), (extent[0], extent[2]), ]) # 添加陆地并应用裁剪 land_feature = ax.add_feature(cfeature.LAND, transform=ccrs.PlateCarree()) land_feature.set_clip_path(clip_path, transform=ccrs.PlateCarree()) ax.add_feature(cfeature.COASTLINE, transform=ccrs.PlateCarree()) plt.show()
内容的提问来源于stack exchange,提问作者Luis
相关产品推荐
相关产品推荐

