简体   繁体   English

使用极立体投影在 cartopy 中放置纬度标签

[英]Placement of latitude labels in cartopy with polar stereographic projection

I am trying to figure out how to change the placement of gridline labels (more specifically, latitude labels) in cartopy when using a polar stereographic projection ( NorthPolarStereo ).我试图弄清楚如何在使用极地立体投影 ( NorthPolarStereo ) 时更改网格线标签(更具体地说,纬度标签)在 cartopy 中的位置。 My axis currently looks like this:我的轴目前看起来像这样:

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)

具有默认网格线标签位置的极地立体图

Oddly, the latitude labels are always plotted at about 150E even if the central_longitude is set to a different value.奇怪的是,即使central_longitude设置为不同的值,纬度标签始终绘制在大约 150E 处。 Preferably, I'd like to align them with the 180th meridian (similar to the labels in this plot ) but I cannot find an option in the documentation of the gridlines function to set their position. Did I overlook something or would I have to place them manually with plt.text()最好,我想将它们与第 180 条子午线对齐(类似于此 plot中的标签),但我无法在gridlines function 的文档中找到一个选项来设置它们的 position。我是忽略了什么还是必须放置他们用plt.text()手动

After the gridlines is created, some labels can be accessed and moved to new positions.创建gridlines后,可以访问一些标签并将其移动到新位置。 I use alternate method to define the circular boundary of the plot in order not to interfere with gridlines' labels.我使用替代方法定义 plot 的圆形边界,以免干扰网格线的标签。

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

输出1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM