python 极赤平投影Map中纬度标注的设置

5tmbdcev  于 2023-02-21  发布在  Python
关注(0)|答案(2)|浏览(170)

我试图弄清楚在使用极赤平投影(NorthPolarStereo)时,如何在Cartopy中更改网格线标签(更具体地说,纬度标签)的位置。

import matplotlib.pyplot as plt
import matplotlib.path as mpath
import numpy as np
import cartopy.crs as ccrs

# Helper function
# from https://nordicesmhub.github.io/NEGI-Abisko-2019/training/example_NorthPolarStereo_projection.html
def polarCentral_set_latlim(lat_lims, ax):
    ax.set_extent([-180, 180, lat_lims[0], lat_lims[1]], ccrs.PlateCarree())
    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)

fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(1,1,1,projection=ccrs.NorthPolarStereo(central_longitude=0))
ax.coastlines(linewidth=0.5,color='k')
ax.gridlines(color='C7',lw=1,ls=':',draw_labels=True,rotate_labels=False,ylocs=[60,70,80])
polarCentral_set_latlim((50,90),ax)

奇怪的是,即使central_longitude设置为不同的值,纬度标签也总是绘制在大约150E处。我想把它们对准180度经线(类似于this plot中的标签),但我在gridlines函数的文档中找不到设置它们位置的选项。我是否忽略了某些内容,或者我必须使用plt.text()手动放置它们

ni65a41a

ni65a41a1#

创建gridlines后,可以访问一些标签并将其移动到新位置。我使用替代方法定义绘图的圆形边界,以免干扰网格线的标签。

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import numpy as np

# Value for r_extent is obtained by trial and error
# get it with `ax.get_ylim()` after running this code
r_extent = 4651194.319
r_extent *= 1.005       #increase a bit for better result

# Projection settings  
lonlat_proj = ccrs.PlateCarree()
use_proj = ccrs.NorthPolarStereo(central_longitude=0)
fig = plt.figure(figsize=[7, 7])
ax = plt.subplot(1, 1, 1, projection=use_proj)
ax.set_extent([-180, 180, 50, 90], lonlat_proj)

#ax.stock_img() # add bluemarble image
ax.coastlines(lw=0.5, color="black", zorder=20) # add coastlines

# draw graticule (meridian and parallel lines)
gls = ax.gridlines(draw_labels=True, crs=lonlat_proj, lw=1, color="gray",
        y_inline=True, xlocs=range(-180,180,30), ylocs=range(0,90,10))

# set the plot limits
ax.set_xlim(-r_extent, r_extent)
ax.set_ylim(-r_extent, r_extent)

# Prep circular boundary
circle_path = mpath.Path.unit_circle()
circle_path = mpath.Path(circle_path.vertices.copy() * r_extent,
                           circle_path.codes.copy())

#set circular boundary
#this method will not interfere with the gridlines' labels 
ax.set_boundary(circle_path)
ax.set_frame_on(False)  #hide the boundary frame

plt.draw()  # Enable the use of `gl._labels`

# Reposition the tick labels
# Labels at 150d meridian will be moved to 180d
for ea in gls._labels:
    # No _labels if not run `plt.draw()`
    pos = ea[2].get_position()
    #print("Position:", pos[0], pos[1])
    if (pos[0]==150):
        ea[2].set_position([180, pos[1]])

plt.show()

r8uurelv

r8uurelv2#

可能是因为我用的是cartopy版本(0.21.1),但是@swatchai的答案对我不起作用。不过可以做一个小小的改变,效果会很好。

plt.draw()
for ea in gls.label_artists:
    # return ea of mpl.text type, e.g. Text(135, 30, '30°N') 
    pos = ea.get_position()
    if pos[0] == 135:
        ea.set_position([180, pos[1]])

相关问题