如何在Python中绘制带旋转坐标网格的摩尔魏德投影全天空图?
实现带任意旋转中心的摩尔魏德投影(Mollweide)绘图
要在Python中实现中心偏离赤道的摩尔魏德投影,Cartopy可以通过自定义旋转坐标系结合常规摩尔魏德投影来实现,核心思路是先将原始经纬度坐标转换到以目标点为中心的旋转坐标系,再用摩尔魏德投影绘制。以下是针对你需求(中心经度-105°、纬度+35°)的具体实现方案:
关键原理
摩尔魏德投影本身默认以赤道0°经度为中心,无法直接设置中心纬度。我们需要先通过RotatedPole坐标系将目标中心点(-105°E, 35°N)映射为旋转后坐标系的赤道0°经度点,再对旋转后的坐标系应用摩尔魏德投影,即可得到目标效果。
代码实现
import matplotlib.pyplot as plt import cartopy.crs as ccrs import numpy as np # 定义目标中心坐标 target_lon = -105 target_lat = 35 # 计算旋转坐标系的极点参数:将目标点转为新坐标系的赤道中心 # 旋转极点纬度 = 90° - 目标中心纬度 # 旋转极点经度 = 目标中心经度 + 180° pole_lat = 90 - target_lat pole_lon = target_lon + 180 # 创建旋转坐标系 rotated_crs = ccrs.RotatedPole(pole_longitude=pole_lon, pole_latitude=pole_lat) # 创建摩尔魏德投影(以旋转坐标系的0°经度为中心) mollweide_crs = ccrs.Mollweide(central_longitude=0) fig, ax = plt.subplots(figsize=(10, 5), subplot_kw={'projection': mollweide_crs}) # 绘制背景和网格 ax.set_global() ax.stock_img() # 绘制旋转后的经纬度网格:使用旋转坐标系生成网格线 # 自定义网格间隔 lon_ticks = np.arange(-180, 181, 30) lat_ticks = np.arange(-90, 91, 30) ax.gridlines(crs=rotated_crs, draw_labels=True, xlocs=lon_ticks, ylocs=lat_ticks, color='gray', linestyle='--') # 可选:标记目标中心点 ax.plot(target_lon, target_lat, 'ro', markersize=8, transform=ccrs.PlateCarree()) plt.title('Mollweide Projection Centered at (-105°E, 35°N)') plt.show()
代码解释
- 旋转坐标系参数计算:通过将目标中心的对跖点作为旋转极点,实现把目标点映射到新坐标系的赤道中心位置,这样摩尔魏德投影就能以该点为中心展示。
- 网格线处理:指定
gridlines的crs为旋转坐标系,这样绘制的网格会自动适配旋转后的投影中心,与你参考的IDL效果一致。 - 坐标转换:所有原始经纬度数据(包括标记点)需要通过
transform=ccrs.PlateCarree()转换到绘图坐标系。
替代方案(手动坐标转换)
如果你需要更底层的控制,可以手动对经纬度进行旋转转换,再传入摩尔魏德投影:
# 使用pyproj手动旋转坐标 from pyproj import Transformer # 定义原始坐标系到旋转坐标系的转换器 transformer = Transformer.from_crs( ccrs.PlateCarree().proj4_init, rotated_crs.proj4_init, always_xy=True ) # 对原始经纬度网格进行转换 lon_grid, lat_grid = np.meshgrid(np.arange(-180, 181, 10), np.arange(-90, 91, 10)) rotated_lon, rotated_lat = transformer.transform(lon_grid, lat_grid) # 然后用rotated_lon和rotated_lat在摩尔魏德投影上绘图
内容的提问来源于stack exchange,提问作者Jonathan Gasser
相关产品推荐
相关产品推荐

