You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将GeoPandas多边形质心坐标映射到Matplotlib坐标?

用GeoPandas质心定位Matplotlib子图的正确姿势

直接手动归一化地理坐标到Matplotlib的图坐标之所以会出错,是因为没考虑到Matplotlib的轴变换(比如图例占用空间、地图投影的非线性映射)。正确的做法是利用Matplotlib内置的坐标转换工具,一步完成地理坐标到图归一化坐标的映射。

完整实现代码

import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt

# 读取 shp 文件并准备数据
map_gdf = gpd.read_file("my_shapefile.shp")
map_gdf["values"] = np.random.rand(len(map_gdf))

# 创建画布和地图轴
fig, ax = plt.subplots(1, 1, figsize=(15, 15))
map_gdf.plot(column="values", ax=ax, legend=True, cmap="Reds")

# 计算多边形质心
map_gdf["county_centers"] = map_gdf.geometry.centroid

# 取第一个质心作为子图位置示例
centroid = map_gdf["county_centers"][0]

# 关键:将地理坐标转换为图的归一化坐标(0-1范围)
# 1. 先把地理坐标转成画布上的显示坐标
display_coords = ax.transData.transform((centroid.x, centroid.y))
# 2. 再把显示坐标转成图的归一化坐标(相对于整个画布)
fig_coords = fig.transFigure.inverted().transform(display_coords)

# 用转换后的坐标添加子图,偏移一半宽度让子图中心对齐质心
subax = fig.add_axes([fig_coords[0] - 0.05,
                      fig_coords[1] - 0.05,
                      0.1,
                      0.1])

subax.pie([0.2, 0.8], labels=["A", "B"])
plt.show()

关键逻辑说明

  • ax.transData.transform():把地理坐标系的点转换为画布显示坐标系(以像素为单位,原点是画布左下角)
  • fig.transFigure.inverted().transform():把显示坐标系的点转换为画布归一化坐标系(范围0-1,(0,0)对应画布左下角,(1,1)对应右上角)
  • 子图位置减去0.05(子图宽度/高度的一半),是为了让子图中心和质心对齐,避免子图左下角和质心重合的偏移问题

手动归一化失效的原因

你之前的手动计算只用到了数据的total_bounds,但忽略了这些关键因素:

  • 地图轴会自动添加边距,实际显示范围和数据原生范围不一致
  • 图例、坐标轴标签等元素会占用画布空间,导致地图轴并非铺满整个画布
  • 带投影的地理数据,坐标的线性归一化会和实际显示位置产生较大偏差

内容的提问来源于stack exchange,提问作者derM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:51:06