南极立体投影的网格线标签(地图边缘的标签)。

huangapple go评论72阅读模式
英文:

grid line labeling (labels around the map's border) for a South Polar Stereo projection

问题

我正在使用南极极射投影来创建南极地图。我已经使用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()

输出结果如下:

南极立体投影的网格线标签(地图边缘的标签)。

我期望的效果如下:

南极立体投影的网格线标签(地图边缘的标签)。

英文:

I'm using the South Polar Stereographic projection to create a map of Antarctica. I've been able to create the gridlines using Cartopy, but the labels for the gridlines are not circular around the map, which is what I want. Is there a way to make the gridline labels follow the circular pattern of the South Polar Stereographic projection? Here's the code I'm currently using:

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()

The output looks like

南极立体投影的网格线标签(地图边缘的标签)。

What I am expecting:

南极立体投影的网格线标签(地图边缘的标签)。

答案1

得分: 2

根据我的知识,以下是您提供的代码部分的翻译:

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpath  # 用于圆形边界

nonproj = ccrs.PlateCarree()  # 用于平面纬度/经度度量

fig = plt.figure(figsize=(7, 7))
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)

# 使网格线成圆形
gls1 = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1,
                    xlocs=range(-180, 171, 10), ylocs=[],
                    color='gray', alpha=0.5, linestyle='--', zorder=10)
gls2 = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1,
                    xlocs=[], ylocs=None,
                    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)

def plot_text(p1, p2, ax, ang_d, txt):
    """
    在由2个点(p1,p2)定义的位置绘制文本字符串
    该字符串以角度'ang_d'旋转
    用法:
    plot_text([90,-31],[90,-50],ax,45,"45-deg_text")
    由swatchai
    """
    # 绘制文本的位置
    l1 = np.array((p1[0], p1[1]))
    l2 = np.array((p2[0], p2[1]))

    # 绘制文本
    th1 = ax.text(l1[0], l1[1], txt, fontsize=10,
                  transform=nonproj,
                  ha="center",
                  rotation=ang_d, rotation_mode='anchor')

# 在圆形边界外绘制文本标签
for lon in range(-180, 180, 10):
    lat = -33  # 通过检查确定的

    a1, a2 = -29.5, -39  # 通用使用的文本锚点...
    # ... 在某些情况下需要调整

    if lon >= 90 and lon <= 170:
        plot_text([lon, a1 + 2.35], [lon, a2], ax, -lon - 180, str(lon) + "°E")
        # 特殊旋转+移动
    elif lon < -90 and lon >= -170:
        # 需要a1 + 2来使文本与其他文本一致
        plot_text([lon, a1 + 2.5], [lon, a2], ax, -lon + 180, str(-lon) + "°W")
        # 特殊旋转+移动
    elif lon > 0:
        plot_text([lon, a1], [lon, a2], ax, -lon, str(lon) + "°E")
    elif lon == 0:
        plot_text([lon, a1], [lon, a2], ax, lon, str(lon) + "°")
    elif lon == -180:
        plot_text([lon, a1 + 2.2], [lon, a2], ax, lon + 180, str(-lon) + "°")
    else:
        plot_text([lon, a1], [lon, a2], ax, -lon, str(-lon) + "°W")
        pass

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

plt.tight_layout()
plt.show()

希望这可以帮助您理解代码的翻译。

英文:

To my knowledge, there is no shortcut for this kind of plot. Special instructions are needed in many places in the code. You can see comments in the code that I added in various places.

Complete code

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as  mpath #for circular boundary
nonproj = ccrs.PlateCarree()  #for plain lat/long degree system
fig = plt.figure(figsize=(7,7))
ax = plt.axes(projection=ccrs.SouthPolarStereo())
ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
ax.add_feature(cfeature.LAND, color=&#39;darkgrey&#39;)
ax.add_feature(cfeature.OCEAN, color=&#39;lightblue&#39;)
ax.add_feature(cfeature.COASTLINE, linewidth=1.25)
# Make the gridlines circular
gls1 = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, \
xlocs=range(-180,171,10), ylocs=[], \
color=&#39;gray&#39;, alpha=0.5, linestyle=&#39;--&#39;, zorder=10)
gls2 = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, \
xlocs=[], ylocs=None, \
color=&#39;gray&#39;, alpha=0.5, linestyle=&#39;--&#39;, 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)
def plot_text(p1, p2, ax, ang_d, txt):
&quot;&quot;&quot;
Plot text string at a location defined by 2 points (p1,p2)
The string is rotated by an angle &#39;ang_d&#39; 
usage:
plot_text([90, -31], [90, -50], ax, 45, &quot;45-deg_text&quot;)
By swatchai
&quot;&quot;&quot;
# Locations to plot text
l1 = np.array((p1[0], p1[1]))
l2 = np.array((p2[0], p2[1]))
# Plot text
th1 = ax.text(l1[0], l1[1], txt, fontsize=10, \
transform=nonproj, \
ha=&quot;center&quot;, \
rotation=ang_d, rotation_mode=&#39;anchor&#39;)
# Plot text labels outside circular boundary
for lon in range(-180,180,10):
lat = -33  # determined by inspection
a1, a2 = -29.5, -39  #text anchor for general use ...
#... need adjustments in some cases
if lon&gt;=90 and lon&lt;=170:
plot_text([lon, a1+2.35], [lon, a2], ax, -lon-180, str(lon)+&quot;&#176;E&quot;)  
# Special rotation+shift
elif lon&lt;-90 and lon&gt;=-170:
# Need a1+2 to move texts in line with others
plot_text([lon, a1+2.5], [lon, a2], ax, -lon+180, str(-lon)+&quot;&#176;W&quot;)  
# Special rotation+shift
elif lon &gt; 0:
plot_text([lon, a1], [lon, a2], ax, -lon, str(lon)+&quot;&#176;E&quot;)
elif lon==0:
plot_text([lon, a1], [lon, a2], ax, lon, str(lon)+&quot;&#176;&quot;)
elif lon==-180:
plot_text([lon, a1+2.2], [lon, a2], ax, lon+180, str(-lon)+&quot;&#176;&quot;)
else:
plot_text([lon, a1], [lon, a2], ax, -lon, str(-lon)+&quot;&#176;W&quot;)
pass
ax.set_boundary(circle, transform=ax.transAxes)
plt.tight_layout()
plt.show()

Output:

南极立体投影的网格线标签(地图边缘的标签)。

huangapple
  • 本文由 发表于 2023年7月31日 22:24:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804560.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定