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

如何让南极立体投影(South Polar Stereo)网格线标签呈环形排列?

问题描述

使用South Polar Stereographic投影制作南极洲地图,通过Cartopy生成了网格线,但网格线标签未按投影的环形分布显示,希望让标签贴合环形样式。

当前代码:

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as  mpath

fig = plt.figure(figsize=(12,8))
ax = plt.axes(projection=ccrs.SouthPolarStereo())
ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
ax.add_feature(cfeature.LAND, color='darkgrey')
ax.add_feature(cfeature.OCEAN, color='lightblue')
ax.add_feature(cfeature.COASTLINE, linewidth=1.25)

# Draw meridian lines with labels around circular boundary
ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, \
                xlocs=range(-180,171,10), ylocs=[], \
                color='gray', alpha=0.5, linestyle='--', zorder=10)
# Draw concentric circles (but hide labels) for the parallels of the latitude
ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, \
                xlocs=[], ylocs=None, \
                color='gray', alpha=0.5, linestyle='--', zorder=10)

# Add circular boundary
theta = np.linspace(0, 2*np.pi, 100)
center, radius = [0.5, 0.5], 0.5
verts = np.vstack([np.sin(theta), np.cos(theta)]).T
circle = mpath.Path(verts * radius + center)

ax.set_boundary(circle, transform=ax.transAxes)


plt.tight_layout()
plt.show()

当前效果:网格线为环形经线和同心圆纬线,但经线标签是水平排列,未沿环形边界弯曲或旋转贴合环形方向。

预期效果:经线标签沿地图的环形边界呈旋转排列,贴合南极投影的圆形轮廓,每个经度标签对应其经线的方向。


解决方案

Cartopy默认的gridlines方法生成的标签不会自动适应极投影的环形排列,需要手动调整标签的旋转角度和位置,以下是两种可行方法:

方法1:自定义Gridliner标签旋转

通过获取Gridliner对象,遍历标签并根据经度计算旋转角度,让标签沿环形方向对齐:

修改后的完整代码:

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpath

fig = plt.figure(figsize=(12,8))
ax = plt.axes(projection=ccrs.SouthPolarStereo())
ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
ax.add_feature(cfeature.LAND, color='darkgrey')
ax.add_feature(cfeature.OCEAN, color='lightblue')
ax.add_feature(cfeature.COASTLINE, linewidth=1.25)

# 绘制网格线并获取Gridliner对象
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, 
                  xlocs=range(-180,171,10), ylocs=[], 
                  color='gray', alpha=0.5, linestyle='--', zorder=10)
# 隐藏不需要的纬线标签
gl.ylabels_right = False
gl.ylabels_left = False

# 遍历经度标签,调整旋转角度和位置
for lon, label in zip(gl.xlocs, gl.xlabels):
    # 计算对应经度的旋转角度,适配南极投影视角
    angle = np.deg2rad(lon)
    label_rot = np.rad2deg(angle) if lon <= 180 else np.rad2deg(angle) - 360
    # 调整旋转方向,避免文字倒转
    if 90 < lon < 270:
        label_rot += 180
    label.set_rotation(label_rot)
    # 设置标签对齐方式,确保贴合环形边界
    label.set_horizontalalignment('center')
    label.set_verticalalignment('bottom')

# 绘制同心圆纬线(无标签)
ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, 
             xlocs=[], ylocs=np.arange(-80, -29, 10), 
             color='gray', alpha=0.5, linestyle='--', zorder=10)

# 添加圆形边界
theta = np.linspace(0, 2*np.pi, 100)
center, radius = [0.5, 0.5], 0.5
verts = np.vstack([np.sin(theta), np.cos(theta)]).T
circle = mpath.Path(verts * radius + center)
ax.set_boundary(circle, transform=ax.transAxes)

plt.tight_layout()
plt.show()

方法2:手动绘制环形标签

如果需要更精准的控制,可使用Matplotlib的text方法手动在环形边界外侧添加标签:

在原有代码基础上替换网格线标签部分为以下代码:

# 绘制无标签的经线网格
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, 
                  xlocs=range(-180,171,10), ylocs=[], 
                  color='gray', alpha=0.5, linestyle='--', zorder=10)

# 手动添加环形经度标签
theta = np.deg2rad(gl.xlocs)
# 标签半径(比地图边界稍大,确保显示在外侧)
r = 0.52
# 计算标签的轴坐标位置
x = center[0] + r * np.sin(theta)
y = center[1] + r * np.cos(theta)

for lon, tx, ty in zip(gl.xlocs, x, y):
    # 计算文字旋转角度,确保正向可读
    rot = np.rad2deg(np.deg2rad(lon))
    if 90 < lon < 270:
        rot += 180
    # 添加标签
    ax.text(tx, ty, f'{lon}°', transform=ax.transAxes,
            ha='center', va='center', rotation=rot, fontsize=9)

关键说明

  • 南极投影下,经度对应的旋转角度需要特殊调整,避免标签倒转。
  • 使用ax.transAxes坐标系可以方便地在环形边界外侧定位标签。
  • 方法1简洁高效,方法2更灵活,可自定义标签样式和位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:43:22