如何将GeoDataFrame与Basemap正确叠加并显示经纬度网格?
解决GeoDataFrame与Basemap莫尔韦德投影叠加显示异常问题
问题原因
你的GeoDataFrame已经是**ESRI:54009(莫尔韦德投影)**的投影坐标,但Basemap创建的绘图轴有自己的投影转换逻辑。直接用gdf.plot(ax=ax)时,GeoPandas会把投影坐标当作普通笛卡尔坐标绘制,和Basemap的坐标空间不匹配,导致显示异常。
解决方案
方法一:转地理坐标后通过Basemap转换绘制
先把GeoDataFrame转成WGS84(EPSG:4326)地理坐标,再用Basemap的投影函数转换坐标后绘制,确保坐标空间统一:
import geopandas as gpd from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt # 读取并转换坐标 gdf = gpd.read_file('myfile.shp') gdf_wgs84 = gdf.to_crs(epsg=4326) # 创建莫尔韦德投影的Basemap map = Basemap(projection='moll', lon_0=0, lat_0=0, resolution='c') # 创建画布并绘制底图元素 fig, ax = plt.subplots(figsize=(10, 6)) map.drawcoastlines() map.drawcountries() map.drawparallels(range(-90, 91, 30), labels=[1,0,0,0], fontsize=10) map.drawmeridians(range(-180, 181, 60), labels=[0,0,0,1], fontsize=10) # 遍历要素转换坐标并绘制 for geom in gdf_wgs84.geometry: if geom.type == 'Point': x, y = map(geom.x, geom.y) ax.plot(x, y, 'ro', markersize=5) elif geom.type in ['Polygon', 'MultiPolygon']: # 处理多边形/多多边形 polygons = geom.geoms if geom.type == 'MultiPolygon' else [geom] for poly in polygons: lons, lats = zip(*list(poly.exterior.coords)) x, y = map(lons, lats) ax.fill(x, y, color='red', alpha=0.5) plt.show()
方法二:匹配Basemap的投影参数直接绘制
获取Basemap的Proj4投影字符串,将GeoDataFrame的CRS与之匹配后直接绘制,确保坐标空间一致:
import geopandas as gpd from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt # 读取数据 gdf = gpd.read_file('myfile.shp') # 创建Basemap实例并获取投影参数 map = Basemap(projection='moll', lon_0=0, lat_0=0, resolution='c') proj4_str = map.proj4string # 统一CRS gdf = gdf.to_crs(proj4_str) # 创建画布并关联Basemap轴 fig = plt.figure(figsize=(10, 6)) ax = fig.add_subplot(111) # 绘制底图 map.drawcoastlines(ax=ax) map.drawcountries(ax=ax) map.drawparallels(range(-90, 91, 30), labels=[1,0,0,0], fontsize=10, ax=ax) map.drawmeridians(range(-180, 181, 60), labels=[0,0,0,1], fontsize=10, ax=ax) # 绘制GeoDataFrame gdf.plot(ax=ax, color='red', markersize=5) plt.show()
内容的提问来源于stack exchange,提问作者emax
相关产品推荐
相关产品推荐

