GeoPandas地图叠加散点/圆补丁后边框不显示问题求助
问题:GeoPandas地图边框不显示,仅显示散点和圆形补丁
使用GeoPandas绘制地图并叠加散点图、圆形补丁后,输出仅显示散点和补丁,地图边框消失。单独运行地图绘制代码可正常显示。
相关代码
def plot_dbscan(points, dbscan, title, pt_sizer=1, plot_circles=False): # 提取噪声点和聚类点 noise = points[dbscan.labels_ == -1] clusters = points[dbscan.labels_ != -1] # 绘制国家边框 fig, ax = plt.subplots(1, figsize=(12,8)) map_1_prj.plot(ax=ax, fc='None', ec='k', linewidth=1.5) # 绘制散点图,支持点大小调整 sns.scatterplot(x=noise[:,0], y=noise[:,1], ax=ax, alpha=1, s=2*pt_sizer, color='gray') sns.scatterplot(x=clusters[:,0], y=clusters[:,1], ax=ax, s=4*pt_sizer, color='red') # 可选:为每个聚类绘制最小外接圆 if plot_circles: for label in np.unique(dbscan.labels_): if label != -1: cluster_points = points[dbscan.labels_ == label] # 计算最小外接圆 (center_x, center_y), radius = minimum_bounding_circle(cluster_points) # 添加圆形补丁 circle_patch = mpatches.Circle((center_x, center_y), radius=radius, fc='None', ec='yellow', linewidth=2) ax.add_patch(circle_patch) ax.axis('equal') # 限制绘图范围到地震数据边界 ax.set_xlim(gdf_prj.total_bounds[0], gdf_prj.total_bounds[2]) ax.set_ylim(gdf_prj.total_bounds[1], gdf_prj.total_bounds[3]) # 手动创建图例项 Ph_border = mlines.Line2D([], [], color='k', linewidth=1.5, label='Philippine Border') noise_l = mlines.Line2D([], [], marker='.', linewidth=0, markersize=4, color='gray', label='Noise') mec = 'yellow' if plot_circles else 'None' clusters_l = mlines.Line2D([], [], marker='.', linewidth=0, markersize=12, color='red', markeredgecolor=mec, label='DBSCAN Clusters') # 添加图例 plt.legend(handles=[Ph_border, noise_l, clusters_l]) plt.title(title) plt.show()
效果图

排查与解决方法
1. 检查坐标参考系(CRS)一致性
地图边框不显示最常见的原因是图层投影不匹配:
- 确认
map_1_prj(地图边框数据)、gdf_prj(用于设置范围的GeoDataFrame)和points(散点数据)使用的是同一个CRS。 - 可以通过打印
map_1_prj.crs、gdf_prj.crs验证,若不一致,需用to_crs()统一投影:# 将gdf_prj转换为map_1_prj的投影 gdf_prj = gdf_prj.to_crs(map_1_prj.crs) # 确保points的坐标也对应该投影下的坐标值
2. 检查绘图范围设置
代码中ax.set_xlim和ax.set_ylim限制了绘图范围到gdf_prj的边界,若该范围小于map_1_prj的范围,会导致地图边框被裁剪:
- 先注释掉这两行代码,运行后查看地图边框是否显示。如果显示,说明是范围设置问题,需调整为包含地图边框的范围:
# 合并地图边框和数据的边界,确保完整显示 combined_xlim = (min(map_1_prj.total_bounds[0], gdf_prj.total_bounds[0]), max(map_1_prj.total_bounds[2], gdf_prj.total_bounds[2])) combined_ylim = (min(map_1_prj.total_bounds[1], gdf_prj.total_bounds[1]), max(map_1_prj.total_bounds[3], gdf_prj.total_bounds[3])) ax.set_xlim(combined_xlim) ax.set_ylim(combined_ylim)
3. 调整绘图顺序与图层层级
虽然通常先画底图再画上层元素,但某些情况下图层渲染顺序可能异常,可尝试明确设置图层层级:
# 先绘制散点,再绘制地图边框并设置层级为最底层 sns.scatterplot(...) sns.scatterplot(...) map_1_prj.plot(ax=ax, fc='None', ec='k', linewidth=1.5, zorder=0)
通过zorder参数确保地图边框在最底层(zorder值越小,图层越靠下)。
4. 验证地图数据有效性
确认map_1_prj的几何数据没有空值或错误:
print(map_1_prj.isna().sum()) # 检查是否有空几何 map_1_prj = map_1_prj.dropna(subset=['geometry']) # 移除空几何行
内容的提问来源于stack exchange,提问作者Gino Penaflor
相关产品推荐
相关产品推荐

