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

如何为南极立体投影创建圆形网格线标签?

南极极地投影网格线标签圆形环绕解决方案

我使用South Polar Stereographic投影制作南极地图,已通过Cartopy生成网格线,但网格线标签未呈圆形环绕地图,希望标签能贴合该投影的圆形样式。当前使用的代码如下:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
import matplotlib.path 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)

# 生成网格线
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, 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()

问题原因

Cartopy默认的网格线标签布局逻辑是为平面投影设计的,在极射投影这类圆形边界的投影中,无法自动让标签沿着圆形边缘排列,导致标签分布杂乱。

解决方案

通过自定义标签绘制逻辑,计算每个标签的位置并调整旋转角度,让标签贴合圆形边界:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
import matplotlib.path as mpath
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

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)

# 设置圆形边界
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)

# 生成网格线但关闭默认标签绘制
gl = ax.gridlines(crs=ccrs.PlateCarree(), linewidth=1, color='gray', alpha=0.5, linestyle='--', zorder=10)
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.draw_labels = False

# 自定义绘制圆形环绕的标签
# 定义要显示的经度间隔和固定纬度标签
lon_labels = np.arange(-180, 181, 30)
lat_label = -30  # 对应地图范围的南纬30度

# 绘制经度标签
center_ax = ax.transAxes.transform((0.5, 0.5))  # 地图中心的像素坐标
for lon in lon_labels:
    # 将经纬度转换为投影坐标
    x_proj, y_proj = ax.projection.transform_point(lon, lat_label, ccrs.PlateCarree())
    # 计算标签相对于中心的角度,用于旋转标签使其贴合圆形
    x_pixel, y_pixel = ax.transData.transform((x_proj, y_proj))
    angle = np.degrees(np.arctan2(x_pixel - center_ax[0], y_pixel - center_ax[1])) + 90
    # 绘制标签
    ax.text(x_proj, y_proj, f'{lon}°', 
            ha='center', va='center', 
            rotation=angle,
            transform=ax.projection,
            zorder=11)

# 绘制纬度标签
x_lat, y_lat = ax.projection.transform_point(0, lat_label, ccrs.PlateCarree())
ax.text(x_lat, y_lat, f'{abs(lat_label)}°S',
        ha='center', va='bottom',
        transform=ax.projection,
        zorder=11)

plt.tight_layout()
plt.show()

关键说明

  1. 先关闭网格线的默认标签绘制,改用ax.text手动添加标签
  2. 通过投影转换计算标签在极射投影下的准确位置
  3. 根据标签相对于地图中心的像素角度,旋转标签使其贴合圆形边缘
  4. 可根据需求调整经度间隔、标签字体样式、颜色等参数

内容的提问来源于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.25 22:02:39