如何将Geopandas绘制的几何图形叠加到Cartopy生成的Matplotlib地图上?
解决Geopandas几何对象与Cartopy底图叠加的问题
看起来你现在的核心问题是不小心创建了两个完全独立的绘图窗口:一个是Geopandas单独绘制多边形的窗口,另一个是Cartopy的底图窗口,所以没法合并到一起。要解决这个问题,关键是把Geopandas的几何图形直接绘制到Cartopy的投影轴上,同时确保坐标系统的匹配。
问题根源
你当前的代码里,trade_geo_df['geometry'].plot()会自动创建一个新的matplotlib轴(和窗口),而Cartopy的图是在另一个新建的fig和ax里,两者完全独立。另外,你的GeoDataFrame没有显式设置坐标参考系统(CRS),Geopandas没法正确识别坐标格式,导致叠加时位置错误或者直接不显示。
修复步骤 & 修改后的完整代码
下面是调整后的代码,我标注了关键修改点:
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER import cartopy.io.img_tiles as cimgt import cartopy.crs as ccrs # 补充你遗漏的Cartopy投影导入 import geopandas as gpd from matplotlib import pyplot as plt import shapely.geometry # 确保导入shapely模块 # 处理GeoDataFrame数据 trade_geo_df = trade_area_response.json()['data'] trade_geo_df = gpd.GeoDataFrame(trade_geo_df) trade_geo_df.loc[:, 'coordinates'] = trade_geo_df.coordinates.map(lambda x: x[0]) trade_geo_df['geometry'] = trade_geo_df.coordinates.apply(shapely.geometry.Polygon) # 关键修改1:给GeoDataFrame设置正确的CRS(你的数据是经纬度,对应EPSG:4326/WGS84) trade_geo_df = trade_geo_df.set_crs("EPSG:4326") # 创建Cartopy的绘图容器(保留你原有设置) fig = plt.figure() stamen_terrain = cimgt.Stamen('terrain-background') ax = fig.add_subplot(1, 1, 1, projection=stamen_terrain.crs) ax.set_extent([-89, -86, 41, 43], crs=ccrs.Geodetic()) # 添加网格线与标签(保留你原有设置) gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=2, color='gray', alpha=0.5, linestyle='--') gl.ylabels_right = False gl.xlabels_top = False gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER gl.xlabel_style = {'size': 10, 'color': 'gray'} gl.ylabel_style = {'size': 10, 'color': 'gray'} # 添加底图瓦片 ax.add_image(stamen_terrain, 8) # 关键修改2:把Geopandas多边形绘制到Cartopy的轴上 # 指定ax=ax绑定到Cartopy轴,transform参数告诉程序:原始数据是经纬度,需要转换到底图投影 trade_geo_df.plot(ax=ax, transform=ccrs.PlateCarree(), edgecolor='darkblue', facecolor='lightblue', alpha=0.6, zorder=3) # 绘制红点(只需要这一次,和底图在同一个轴上) ax.plot(placer_lng, placer_lat, markersize=5, marker='o', color='red', transform=ccrs.Geodetic(), zorder=4) plt.show()
关键修改说明
- 设置GeoDataFrame的CRS:因为你的多边形坐标是经纬度格式,必须显式设置
set_crs("EPSG:4326"),让Geopandas明确坐标系统,才能正确转换到Cartopy的底图投影。 - 绑定Cartopy轴绘制几何图形:调用
trade_geo_df.plot()时,通过ax=ax指定要绘制到Cartopy的轴上,transform=ccrs.PlateCarree()参数告诉绘图工具:原始几何数据是经纬度,需要转换为当前底图的投影坐标。 - 移除独立绘图调用:删掉原来的
trade_geo_df['geometry'].plot()和对应的红点绘制,避免创建额外的独立窗口。
额外排查提示
如果多边形还是不显示,可以试试:
- 确认你的多边形坐标确实在
ax.set_extent指定的经纬度范围内(你的数据看起来是符合的) - 调整多边形的颜色、透明度(比如
alpha=0.6)或zorder值(比如zorder=3),避免被底图遮挡 - 可以单独打印
trade_geo_df.total_bounds,查看数据的经纬度范围是否和底图范围匹配
内容的提问来源于stack exchange,提问作者DomM




