our*_*nos 5 projection matplotlib cartopy
我想在 Cartopy 中以 NorthPolarStereo 投影绘制圆圈,并以经纬度单位提供中心和半径。
类似和优秀的问题和答案可用于此处的底图,以及此处的正射投影中的Cartopy找到有关正射投影中的 Cartopy 的问题和答案。但是,我想在 Cartopy 中使用 NorthPolarStereo。尝试后一种方法,只需更改投影即可使圆固定在北极,忽略您为其中心提供的坐标。
关于如何使用 NorthPolarStereo 投影在 Cartopy 中绘制圆圈的任何想法,并以纬度、经度提供其中心和半径?
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()
Run Code Online (Sandbox Code Playgroud)
圆心坐标必须是投影坐标。因此,需要进行坐标变换。
这是相关代码:
# 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))
Run Code Online (Sandbox Code Playgroud)
输出图将是:
替代解决方案
由于使用的投影是conformal
,因此其上的 Tissot Indicatrix 图将始终是圆形。这样,您需要的圆就可以用指示器来表示。这是您可以尝试的代码:
ax.tissot(rad_km=r_ortho/1000, lons=lon, lats=lat, n_samples=48, color='green', \
alpha=0.3, zorder=31)
Run Code Online (Sandbox Code Playgroud)
编辑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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1921 次 |
最近记录: |