Matplotlib 在NorthPolarStereo投影中使用Cartopy绘制圆

Matplotlib 在NorthPolarStereo投影中使用Cartopy绘制圆,matplotlib,projection,cartopy,Matplotlib,Projection,Cartopy,我想在NorthPolarStereo投影中用Cartopy绘制圆圈,提供以lat、lon单位表示的中心和半径 类似和优秀的问题和答案可用于Basemap和Ortographic投影中的Cartopy。但是,我想在Cartopy中使用NorthPolarStereo。尝试后一种方法,只需更改投影,即可使圆固定在北极,忽略为其中心提供的坐标 关于如何使用NorthPolarStereo投影在Cartopy中绘制圆,并在lat,lon untis中提供圆心和半径,有什么想法吗? import num

我想在NorthPolarStereo投影中用Cartopy绘制圆圈,提供以lat、lon单位表示的中心和半径

类似和优秀的问题和答案可用于Basemap和Ortographic投影中的Cartopy。但是,我想在Cartopy中使用NorthPolarStereo。尝试后一种方法,只需更改投影,即可使圆固定在北极,忽略为其中心提供的坐标

关于如何使用NorthPolarStereo投影在Cartopy中绘制圆,并在lat,lon untis中提供圆心和半径,有什么想法吗?

import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

# example: draw circle with 45 degree radius around the North pole
lat = 72 
lon = 100
r = 20

# Define the projection used to display the circle:
proj = ccrs.NorthPolarStereo(central_longitude=lon)


def compute_radius(ortho, radius_degrees):
    phi1 = lat + radius_degrees if lat <= 0 else lat - radius_degrees
    _, y1 = ortho.transform_point(lon, phi1, ccrs.PlateCarree())
    return abs(y1)

# Compute the required radius in projection native coordinates:
r_ortho = compute_radius(proj, r)

# We can now compute the correct plot extents to have padding in degrees:
pad_radius = compute_radius(proj, r + 5)

# define image properties
width = 800
height = 800
dpi = 96
resolution = '50m'

# create figure
fig = plt.figure(figsize=(width / dpi, height / dpi), dpi=dpi)
ax = fig.add_subplot(1, 1, 1, projection=proj)

ax.set_xlim([-pad_radius, pad_radius])
ax.set_ylim([-pad_radius, pad_radius])
ax.imshow(np.tile(np.array([[cfeature.COLORS['water'] * 255]], dtype=np.uint8), [2, 2, 1]), origin='upper', transform=ccrs.PlateCarree(), extent=[-180, 180, -180, 180])
ax.add_feature(cfeature.NaturalEarthFeature('physical', 'land', resolution, edgecolor='black', facecolor=cfeature.COLORS['land']))
ax.add_patch(mpatches.Circle(xy=[lon, lat], radius=r_ortho, color='red', alpha=0.3, transform=proj, zorder=30))

plt.show()
将numpy导入为np
将cartopy.crs作为CCR导入
将cartopy.feature导入为cfeature
将matplotlib.pyplot作为plt导入
将matplotlib.patches作为MPatch导入
#示例:围绕北极绘制半径为45度的圆
lat=72
lon=100
r=20
#定义用于显示圆的投影:
项目=北极圈(中心经度=lon)
def计算半径(正交、半径度):

phi1=纬度+半径_度如果纬度则圆心坐标必须为投影坐标。因此,需要进行坐标变换

以下是相关代码:

# Note: lat = 72, lon = 100
# proj = ccrs.NorthPolarStereo(central_longitude=lon)

projx1, projy1 = proj.transform_point(lon, lat, ccrs.Geodetic()) #get proj coord of (lon,lat)
ax.add_patch(mpatches.Circle(xy=[projx1, projy1], radius=r_ortho, color='red', \
                            alpha=0.3, transform=proj, zorder=30))
输出图将为:

替代解决方案

由于使用的投影是保形的,因此其上的天梭指示图将始终是一个圆。因此,您需要的圆可以用一个指示符表示。以下是您可以尝试的代码:

ax.tissot(rad_km=r_ortho/1000, lons=lon, lats=lat, n_samples=48, color='green', \
      alpha=0.3, zorder=31)
编辑1

替换错误功能的代码:

import pyproj

def compute_radius(val_degree):
    """
    Compute surface distance in meters for a given angular value in degrees
    """
    geod84 = pyproj.Geod(ellps='WGS84')
    lat0, lon0 = 0, 90
    _, _, dist_m = geod84.inv(lon0, lat0,  lon0+val_degree, lat0)
    return dist_m

compute_radius(1)  # get: 111319.49079327357 (meters)

谢谢你的解决方案。但是,我希望半径
r
以度表示。例如,如果我减小r=1,我仍然会得到一个大圆圈。我在这里遗漏了什么吗?事实上,半径到投影坐标的转换并不像我预期的那样有效。你能在这里解释一下吗?@ouranos图的范围与
pad\u radius
的值有关,这取决于
r
。当您将
r
的值从20更改为1时,新绘图将覆盖较小的接地范围(但绘图大小相同)。虽然圆的大小在地图上保持不变,但相对而言,它变小了。函数
compute\u radius()
没有给出预期的正确值。@乌拉诺斯我为
compute\u radius()
添加了应该适合您的代码。