使用Cartopy与Matplotlib绘图时投影匹配问题求助
Cartopy+Matplotlib 点投影匹配问题排查与解决
核心问题定位
你的问题本质是数据CRS(坐标参考系统)与绘图轴投影不匹配,加上代码结构限制导致的适配问题,下面针对你尝试的两种场景逐一给出解决方案:
场景1:Matplotlib绘图+Cartopy底图(版本1)
你遇到的底图显示异常、点不显示问题,核心是没理清Cartopy中projection和transform的核心区别:
projection:设置绘图轴的目标投影(即底图使用的CRS)transform:告诉Cartopy你的原始数据使用的CRS(多数GPS/经纬度数据为WGS84,对应EPSG:4326)
修正步骤
- 初始化轴时必须指定
projection为你需要的底图CRS(比如墨卡托、UTM等) - 绘制点时,显式传入
transform=ccrs.PlateCarree()(如果你的数据是经纬度格式) - 调整显示范围时,若使用非PlateCarree投影,不能直接用
xlim/ylim,需用ax.set_extent([lon_min, lon_max, lat_min, lat_max], crs=ccrs.PlateCarree()),这里的crs要和数据CRS一致
示例修正代码
import matplotlib.pyplot as plt import cartopy.crs as ccrs # 初始化带目标投影的Cartopy轴 ax = plt.axes(projection=ccrs.Mercator()) # 添加底图 ax.stock_img() # 假设你的原始数据是经纬度列表 lons = [116, 117, 118] lats = [39, 39.5, 40] # 绘制点,指定数据对应的CRS ax.scatter(lons, lats, transform=ccrs.PlateCarree(), color='red', s=50) # 设置显示范围,用数据CRS定义边界 ax.set_extent([115, 119, 38.5, 40.5], crs=ccrs.PlateCarree()) plt.show()
场景2:使用add_geometries报错(版本2)
错误Source CRS must be an instance of CRS or one of its subclasses, or None.的原因是:
- 传入的几何对象未关联正确的CRS,或
crs参数格式不符合要求(比如传了字符串而非CRS实例)
修正步骤
- 若使用GeoDataFrame存储点数据,先为其显式设置CRS(比如
gdf.set_crs(epsg=4326, inplace=True)) - 调用
add_geometries时,crs参数必须传入Cartopy或GeoPandas的CRS实例,不能直接传字符串(比如用ccrs.PlateCarree()而非"EPSG:4326")
示例修正代码
import geopandas as gpd import cartopy.crs as ccrs import matplotlib.pyplot as plt # 构造带几何对象的GeoDataFrame lons = [116, 117, 118] lats = [39, 39.5, 40] gdf = gpd.GeoDataFrame(geometry=gpd.points_from_xy(lons, lats)) # 为数据绑定CRS gdf.set_crs(epsg=4326, inplace=True) ax = plt.axes(projection=ccrs.Mercator()) ax.stock_img() # 调用add_geometries时传入正确的CRS实例 ax.add_geometries(gdf.geometry, crs=ccrs.PlateCarree(), facecolor='blue', marker='o', s=50) ax.set_extent([115, 119, 38.5, 40.5], crs=ccrs.PlateCarree()) plt.show()
额外建议
- 先确认原始数据的CRS:GPS经纬度数据默认是EPSG:4326(对应Cartopy的
ccrs.PlateCarree()) - 不要混用Matplotlib原生轴和Cartopy轴:必须通过
plt.axes(projection=...)或fig.add_subplot(projection=...)创建Cartopy专属轴 - 若部分代码无法修改,优先封装数据转换逻辑:比如把原始数据转换成带CRS的GeoSeries,再适配绘图代码
内容的提问来源于stack exchange,提问作者Drödembüddel
相关产品推荐
相关产品推荐

