我正在尝试使用 Cartopy 映射一些数据,但我遇到了地图范围问题。当在自身上绘制地图时,Cartopy 显示整个地球(这很棒,这就是我想要的):
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
# Initialise plot
cm = 1/2.54
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15*cm, 8*cm),
subplot_kw={'projection': ccrs.Mollweide()})
# Add land
ax.add_feature(cfeature.NaturalEarthFeature(category='physical',
name='land',
scale='50m'),
facecolor='#ccc',
edgecolor='black',
linewidth=.25,
zorder=1)
# Export
fpath = "figures/test_map1.png"
fig.savefig(fpath, format='png', bbox_inches='tight', dpi=300)
但是当添加一些数据(例如散点数据)时,Cartopy 会自动重置比例以仅显示数据占用的地理区域:
# Create and plot dummy data
xv = [*range(-50, 0)]
yv = [*range(-20, 30)]
ax.scatter(xv,
yv,
edgecolor='red',
s=20,
marker='.',
linewidth=2,
transform=ccrs.PlateCarree(),
zorder=0)
fpath = "figures/test_map2.png"
fig.savefig(fpath, format='png', bbox_inches='tight', dpi=300)
如果手动重置它不会很棘手的话那就没问题了:如果经度限制设置为-180, 180(地图消失,我知道由于限制问题),并且设置-179.9999,则
set_extent()
不起作用,179.9999 在侧面留下小切口:
# Try to reset extent
ax.set_extent([-179.9999, 179.9999, -90, 90], crs=ccrs.PlateCarree())
fpath = "figures/test_map3.png"
fig.savefig(fpath, format='png', bbox_inches='tight', dpi=300)
我的问题对于其他投影来说会变得更糟,例如
NearsidePerspective
,因为对我来说如何知道它们接受的最大程度并不简单[Cartopy 投影文档据我所知并没有解决这个问题]。例如,使用 NearsidePerspective
投影将范围设置为 [-90, 90, -90, 90] 会返回以下错误:
ValueError:轴限制不能为 NaN 或 Inf
设置更多限制范围会产生不令人满意的结果(即,再次,边界切割):
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15*cm, 8*cm),
subplot_kw={'projection': ccrs.NearsidePerspective(
central_longitude=0,
central_latitude=0
)})
ax.add_feature(cfeature.NaturalEarthFeature(category='physical',
name='land',
scale='50m'),
facecolor='#ccc',
edgecolor='black',
linewidth=.25,
zorder=1)
ax.scatter(xv,
yv,
edgecolor='red',
s=20,
marker='.',
linewidth=2,
transform=ccrs.PlateCarree(),
zorder=0)
ax.set_extent([-70, 70, -60, 60], crs=ccrs.PlateCarree())
fpath = "figures/test_map4.png"
fig.savefig(fpath, format='png', bbox_inches='tight', dpi=300)
我也尝试过改变人物的大小和比例,但似乎不起作用。所以,我的问题是:
引用经典全球地图示例中的评论:
# make the map global rather than have it zoom in to # the extents of any plotted data ax.set_global()
set_global
之前添加 scatter
似乎可以解决您的问题(参见 完整代码):