如何在Cartopy中构建正确的南极周边地理要素?
解决南极Cartopy地理要素在多投影下的显示问题
针对你用Cartopy绘制南极附近地理要素时在部分投影下显示效果差的问题,给你几个实用的解决技巧:
1. 生成球面正确的多边形(而非平面直线)
原代码里用lat=-70的直线生成的多边形,在极地投影下会变形——这是平面坐标系里的直线,不是球面上的纬线圆。换用球面距离buffer生成真正的圆形多边形,在任何投影下都能正确显示:
import numpy as np import matplotlib.pyplot as plt import cartopy.crs as ccrs from shapely.geometry import Point # 生成南纬70度对应的球面圆多边形 south_pole = Point(0, -90) # 南纬70度到南极的球面距离:20纬度差×111km/度,转成米 distance = 20 * 111000 # resolution设高一点(比如64)让边缘更光滑 coast_shp = south_pole.buffer(distance, resolution=64) # 这里用ccrs.Geodetic()作为要素的CRS,因为buffer是基于球面距离计算的
2. 解决跨日界线的显示异常
当投影中心经度设为180时,原代码里lon从-180到180的多边形会被日界线切开。改成0到360的经度范围,同时增加顶点数让边缘更光滑:
# 生成0-360经度的南纬70度纬线,用100个点保证平滑 lon_coast = np.linspace(start=0, stop=360, num=100) lat_coast = np.ones(lon_coast.shape) * (-70) # 闭合多边形:把第一个点放到最后,不用加nan coord_coast = np.vstack([np.stack([lon_coast, lat_coast]).T, coord_coast[0]]) coast_shp = shp.Polygon(coord_coast)
3. 用更灵活的方式添加要素
替换cartopy.feature.ShapelyFeature为ax.add_geometries,直接控制要素的CRS,减少转换混淆:
def my_fig(idx, proj): pos = 230 + idx ax = fig.add_subplot(pos, projection=proj) # 用add_geometries直接添加几何对象,指定原始CRS ax.add_geometries([coast_shp], crs=ccrs.Geodetic(), facecolor='green', edgecolor='red') ax.coastlines() ax.gridlines()
4. 极地投影的专属优化
用ccrs.SouthPolarStereo()专门的南极投影,同时限制绘图范围到南极区域,避免不必要的变形:
my_fig(6, ccrs.SouthPolarStereo()) # 限制显示范围在南纬60度以南 ax.set_extent([-180, 180, -90, -60], crs=ccrs.PlateCarree())
修改后的完整测试代码
import numpy as np import matplotlib.pyplot as plt import cartopy.crs as ccrs from shapely.geometry import Point, Polygon # 方法1:生成球面正确的南纬70度圆 south_pole = Point(0, -90) distance = 20 * 111000 # 南纬70到南极的球面距离(米) coast_shp = south_pole.buffer(distance, resolution=64) # 方法2:如果坚持用经纬度生成,用0-360经度 # lon_coast = np.linspace(start=0, stop=360, num=100) # lat_coast = np.ones(lon_coast.shape)*(-70) # coord_coast = np.stack([lon_coast, lat_coast]).T # coord_coast = np.vstack([coord_coast, coord_coast[0]]) # coast_shp = Polygon(coord_coast) fig = plt.figure(figsize=(12, 8)) def my_fig(idx, proj): pos = 230 + idx ax = fig.add_subplot(pos, projection=proj) ax.add_geometries([coast_shp], crs=ccrs.Geodetic(), facecolor='green', edgecolor='red') ax.coastlines() ax.gridlines() # 极地投影添加范围限制 if isinstance(proj, ccrs.SouthPolarStereo): ax.set_extent([-180, 180, -90, -60], crs=ccrs.PlateCarree()) my_fig(1, ccrs.PlateCarree()) my_fig(2, ccrs.Orthographic(central_latitude=-90)) my_fig(3, ccrs.PlateCarree(central_longitude=180)) my_fig(4, ccrs.Robinson(central_longitude=0)) my_fig(5, ccrs.Robinson(central_longitude=180)) my_fig(6, ccrs.SouthPolarStereo()) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Marti
相关产品推荐
相关产品推荐

