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

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

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

问题

我正在使用南极极射投影来创建南极地图。我已经使用Cartopy创建了网格线,但是网格线的标签不是围绕地图的圆形排列,这是我想要的效果。有没有办法使网格线标签遵循南极极射投影的圆形模式?这是我目前正在使用的代码:

  1. import cartopy.crs as ccrs
  2. import cartopy.feature as cfeature
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import matplotlib.patches as mpath
  6. fig = plt.figure(figsize=(12,8))
  7. ax = plt.axes(projection=ccrs.SouthPolarStereo())
  8. ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
  9. ax.add_feature(cfeature.LAND, color='darkgrey')
  10. ax.add_feature(cfeature.OCEAN, color='lightblue')
  11. ax.add_feature(cfeature.COASTLINE, linewidth=1.25)
  12. # Draw meridian lines with labels around circular boundary
  13. ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, \
  14. xlocs=range(-180,171,10), ylocs=[], \
  15. color='gray', alpha=0.5, linestyle='--', zorder=10)
  16. # Draw concentric circles (but hide labels) for the parallels of the latitude
  17. ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, \
  18. xlocs=[], ylocs=None, \
  19. color='gray', alpha=0.5, linestyle='--', zorder=10)
  20. # Add circular boundary
  21. theta = np.linspace(0, 2*np.pi, 100)
  22. center, radius = [0.5, 0.5], 0.5
  23. verts = np.vstack([np.sin(theta), np.cos(theta)]).T
  24. circle = mpath.Path(verts * radius + center)
  25. ax.set_boundary(circle, transform=ax.transAxes)
  26. plt.tight_layout()
  27. 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:

  1. import cartopy.crs as ccrs
  2. import cartopy.feature as cfeature
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import matplotlib.patches as mpath
  6. fig = plt.figure(figsize=(12,8))
  7. ax = plt.axes(projection=ccrs.SouthPolarStereo())
  8. ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
  9. ax.add_feature(cfeature.LAND, color='darkgrey')
  10. ax.add_feature(cfeature.OCEAN, color='lightblue')
  11. ax.add_feature(cfeature.COASTLINE, linewidth=1.25)
  12. # Draw meridian lines with labels around circular boundary
  13. ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, \
  14. xlocs=range(-180,171,10), ylocs=[], \
  15. color='gray', alpha=0.5, linestyle='--', zorder=10)
  16. # Draw concentric circles (but hide labels) for the parallels of the latitude
  17. ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, \
  18. xlocs=[], ylocs=None, \
  19. color='gray', alpha=0.5, linestyle='--', zorder=10)
  20. # Add circular boundary
  21. theta = np.linspace(0, 2*np.pi, 100)
  22. center, radius = [0.5, 0.5], 0.5
  23. verts = np.vstack([np.sin(theta), np.cos(theta)]).T
  24. circle = mpath.Path(verts * radius + center)
  25. ax.set_boundary(circle, transform=ax.transAxes)
  26. plt.tight_layout()
  27. plt.show()

The output looks like

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

What I am expecting:

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

答案1

得分: 2

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

  1. import cartopy.crs as ccrs
  2. import cartopy.feature as cfeature
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import matplotlib.patches as mpath # 用于圆形边界
  6. nonproj = ccrs.PlateCarree() # 用于平面纬度/经度度量
  7. fig = plt.figure(figsize=(7, 7))
  8. ax = plt.axes(projection=ccrs.SouthPolarStereo())
  9. ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
  10. ax.add_feature(cfeature.LAND, color='darkgrey')
  11. ax.add_feature(cfeature.OCEAN, color='lightblue')
  12. ax.add_feature(cfeature.COASTLINE, linewidth=1.25)
  13. # 使网格线成圆形
  14. gls1 = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1,
  15. xlocs=range(-180, 171, 10), ylocs=[],
  16. color='gray', alpha=0.5, linestyle='--', zorder=10)
  17. gls2 = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1,
  18. xlocs=[], ylocs=None,
  19. color='gray', alpha=0.5, linestyle='--', zorder=10)
  20. # 添加圆形边界
  21. theta = np.linspace(0, 2 * np.pi, 100)
  22. center, radius = [0.5, 0.5], 0.5
  23. verts = np.vstack([np.sin(theta), np.cos(theta)]).T
  24. circle = mpath.Path(verts * radius + center)
  25. def plot_text(p1, p2, ax, ang_d, txt):
  26. """
  27. 在由2个点(p1,p2)定义的位置绘制文本字符串
  28. 该字符串以角度'ang_d'旋转
  29. 用法:
  30. plot_text([90,-31],[90,-50],ax,45,"45-deg_text")
  31. 由swatchai
  32. """
  33. # 绘制文本的位置
  34. l1 = np.array((p1[0], p1[1]))
  35. l2 = np.array((p2[0], p2[1]))
  36. # 绘制文本
  37. th1 = ax.text(l1[0], l1[1], txt, fontsize=10,
  38. transform=nonproj,
  39. ha="center",
  40. rotation=ang_d, rotation_mode='anchor')
  41. # 在圆形边界外绘制文本标签
  42. for lon in range(-180, 180, 10):
  43. lat = -33 # 通过检查确定的
  44. a1, a2 = -29.5, -39 # 通用使用的文本锚点...
  45. # ... 在某些情况下需要调整
  46. if lon >= 90 and lon <= 170:
  47. plot_text([lon, a1 + 2.35], [lon, a2], ax, -lon - 180, str(lon) + "°E")
  48. # 特殊旋转+移动
  49. elif lon < -90 and lon >= -170:
  50. # 需要a1 + 2来使文本与其他文本一致
  51. plot_text([lon, a1 + 2.5], [lon, a2], ax, -lon + 180, str(-lon) + "°W")
  52. # 特殊旋转+移动
  53. elif lon > 0:
  54. plot_text([lon, a1], [lon, a2], ax, -lon, str(lon) + "°E")
  55. elif lon == 0:
  56. plot_text([lon, a1], [lon, a2], ax, lon, str(lon) + "°")
  57. elif lon == -180:
  58. plot_text([lon, a1 + 2.2], [lon, a2], ax, lon + 180, str(-lon) + "°")
  59. else:
  60. plot_text([lon, a1], [lon, a2], ax, -lon, str(-lon) + "°W")
  61. pass
  62. ax.set_boundary(circle, transform=ax.transAxes)
  63. plt.tight_layout()
  64. 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

  1. import cartopy.crs as ccrs
  2. import cartopy.feature as cfeature
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import matplotlib.patches as mpath #for circular boundary
  6. nonproj = ccrs.PlateCarree() #for plain lat/long degree system
  7. fig = plt.figure(figsize=(7,7))
  8. ax = plt.axes(projection=ccrs.SouthPolarStereo())
  9. ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
  10. ax.add_feature(cfeature.LAND, color=&#39;darkgrey&#39;)
  11. ax.add_feature(cfeature.OCEAN, color=&#39;lightblue&#39;)
  12. ax.add_feature(cfeature.COASTLINE, linewidth=1.25)
  13. # Make the gridlines circular
  14. gls1 = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, \
  15. xlocs=range(-180,171,10), ylocs=[], \
  16. color=&#39;gray&#39;, alpha=0.5, linestyle=&#39;--&#39;, zorder=10)
  17. gls2 = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, \
  18. xlocs=[], ylocs=None, \
  19. color=&#39;gray&#39;, alpha=0.5, linestyle=&#39;--&#39;, zorder=10)
  20. # Add circular boundary
  21. theta = np.linspace(0, 2*np.pi, 100)
  22. center, radius = [0.5, 0.5], 0.5
  23. verts = np.vstack([np.sin(theta), np.cos(theta)]).T
  24. circle = mpath.Path(verts * radius + center)
  25. def plot_text(p1, p2, ax, ang_d, txt):
  26. &quot;&quot;&quot;
  27. Plot text string at a location defined by 2 points (p1,p2)
  28. The string is rotated by an angle &#39;ang_d&#39;
  29. usage:
  30. plot_text([90, -31], [90, -50], ax, 45, &quot;45-deg_text&quot;)
  31. By swatchai
  32. &quot;&quot;&quot;
  33. # Locations to plot text
  34. l1 = np.array((p1[0], p1[1]))
  35. l2 = np.array((p2[0], p2[1]))
  36. # Plot text
  37. th1 = ax.text(l1[0], l1[1], txt, fontsize=10, \
  38. transform=nonproj, \
  39. ha=&quot;center&quot;, \
  40. rotation=ang_d, rotation_mode=&#39;anchor&#39;)
  41. # Plot text labels outside circular boundary
  42. for lon in range(-180,180,10):
  43. lat = -33 # determined by inspection
  44. a1, a2 = -29.5, -39 #text anchor for general use ...
  45. #... need adjustments in some cases
  46. if lon&gt;=90 and lon&lt;=170:
  47. plot_text([lon, a1+2.35], [lon, a2], ax, -lon-180, str(lon)+&quot;&#176;E&quot;)
  48. # Special rotation+shift
  49. elif lon&lt;-90 and lon&gt;=-170:
  50. # Need a1+2 to move texts in line with others
  51. plot_text([lon, a1+2.5], [lon, a2], ax, -lon+180, str(-lon)+&quot;&#176;W&quot;)
  52. # Special rotation+shift
  53. elif lon &gt; 0:
  54. plot_text([lon, a1], [lon, a2], ax, -lon, str(lon)+&quot;&#176;E&quot;)
  55. elif lon==0:
  56. plot_text([lon, a1], [lon, a2], ax, lon, str(lon)+&quot;&#176;&quot;)
  57. elif lon==-180:
  58. plot_text([lon, a1+2.2], [lon, a2], ax, lon+180, str(-lon)+&quot;&#176;&quot;)
  59. else:
  60. plot_text([lon, a1], [lon, a2], ax, -lon, str(-lon)+&quot;&#176;W&quot;)
  61. pass
  62. ax.set_boundary(circle, transform=ax.transAxes)
  63. plt.tight_layout()
  64. 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:

确定