Cartopy中Mercator投影下点坐标异常问题解析及适配方法
我之前也遇到过类似的困惑,核心问题其实是没搞清楚cartopy里「绘图投影」和「数据坐标转换」的区别,咱们一步步拆解来看:
为什么ccrs.PlateCarree()正常,ccrs.Mercator()却出问题?
- ccrs.PlateCarree()的特殊性:这个投影本质是等距圆柱投影,它的坐标系统直接对应经纬度值(单位是度)。如果你传入的点(6,56)是经度6°E、纬度56°N的地理坐标,那么用PlateCarree作为绘图投影时,数据坐标和投影坐标刚好匹配,不需要额外转换就能正确显示。
- ccrs.Mercator()的坐标差异:Mercator是一种投影坐标系,它的坐标单位是米(或其他线性单位),而非度。如果你直接把经纬度(6,56)当成Mercator的坐标传入,这两个数值太小了,会被解析成距离投影原点极近的位置(接近(0,0)),所以看起来点“丢失”了。
解决方案:明确数据坐标系,让cartopy自动转换
在cartopy绘图时,一定要区分两个关键参数:
projection:指定绘图坐标轴使用的投影(也就是你最终看到的地图样式)transform:指定输入数据的坐标系(告诉cartopy你的原始数据是什么坐标格式)
不管用什么投影,最规范的做法是明确指定transform参数,避免依赖PlateCarree的巧合匹配。举个具体的代码例子:
错误写法(点丢失)
import cartopy.crs as ccrs import matplotlib.pyplot as plt ax = plt.axes(projection=ccrs.Mercator()) ax.plot(6, 56, 'ro') # 错误:把经纬度直接当成Mercator坐标 plt.show()
正确写法(两种方式)
方式1:指定transform参数(推荐)
让cartopy自动帮你把经纬度转换为Mercator投影坐标:
import cartopy.crs as ccrs import matplotlib.pyplot as plt ax = plt.axes(projection=ccrs.Mercator()) # 告诉cartopy:我的数据是经纬度(PlateCarree坐标系),需要转换到Mercator投影 ax.plot(6, 56, 'ro', transform=ccrs.PlateCarree()) ax.set_extent([0, 10, 50, 60]) # 聚焦到点所在的区域,方便查看 plt.show()
方式2:手动转换坐标
如果你想自己处理坐标转换,可以用transform_point方法:
import cartopy.crs as ccrs import matplotlib.pyplot as plt # 定义两个坐标系 data_crs = ccrs.PlateCarree() # 数据是经纬度 plot_crs = ccrs.Mercator() # 绘图用Mercator投影 # 手动转换坐标 x, y = plot_crs.transform_point(6, 56, data_crs) ax = plt.axes(projection=plot_crs) ax.plot(x, y, 'ro') ax.set_extent([0, 10, 50, 60]) plt.show()
总结
本质上你遇到的是坐标系混淆:把地理坐标(经纬度)直接当成了投影坐标(Mercator的米制坐标)。只要明确区分数据坐标系和绘图投影,通过transform参数让cartopy处理转换,就能解决这个问题啦。
内容的提问来源于stack exchange,提问作者ztl
相关产品推荐
相关产品推荐

