好问题。这可能会一次又一次地出现,所以在实际上回答您的具体问题之前,我将逐步完成。为了将来参考,以下示例是使用 cartopy v0.5 编写的。
首先,重要的是要注意默认的“纬度经度”(或者更专业的 PlateCarree)投影在 -180 到 180 的正向范围内工作。这意味着您不能绘制标准PlateCarree 投影超出此范围。这有几个很好的原因,其中大部分归结为这样一个事实,即在投影矢量和栅格(例如简单的海岸线)时,cartopy 必须做更多的工作。不幸的是,您尝试制作的情节正是需要此功能。为了把这个限制放到图片中,默认的 PlateCarree 投影看起来像:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
proj = ccrs.PlateCarree(central_longitude=0)
ax1 = plt.axes(projection=proj)
ax1.stock_img()
plt.title('Global')
plt.show()
您可以在此地图上绘制的任何单个矩形都可以合法地放大区域(这里有一些更高级的代码,但图片值 1000 字):
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
box = sgeom.box(minx=-90, maxx=45, miny=15, maxy=70)
x0, y0, x1, y1 = box.bounds
proj = ccrs.PlateCarree(central_longitude=0)
ax1 = plt.subplot(211, projection=proj)
ax1.stock_img()
ax1.add_geometries([box], proj, facecolor='coral',
edgecolor='black', alpha=0.5)
plt.title('Global')
ax2 = plt.subplot(212, projection=proj)
ax2.stock_img()
ax2.set_extent([x0, x1, y0, y1], proj)
plt.title('Zoomed in area')
plt.show()
不幸的是,您想要的绘图需要 2 个带有此投影的矩形:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
box = sgeom.box(minx=120, maxx=260, miny=15, maxy=80)
proj = ccrs.PlateCarree(central_longitude=0)
ax1 = plt.axes(projection=proj)
ax1.stock_img()
ax1.add_geometries([box], proj, facecolor='coral',
edgecolor='black', alpha=0.5)
plt.title('Target area')
plt.show()
因此,无法使用标准 PlateCarree 定义绘制跨越日期变更线的地图。相反,我们可以更改 PlateCarree 定义的中心经度,以允许在我们的目标区域中绘制一个框:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
box = sgeom.box(minx=120, maxx=260, miny=15, maxy=80)
x0, y0, x1, y1 = box.bounds
proj = ccrs.PlateCarree(central_longitude=180)
box_proj = ccrs.PlateCarree(central_longitude=0)
ax1 = plt.subplot(211, projection=proj)
ax1.stock_img()
ax1.add_geometries([box], box_proj, facecolor='coral',
edgecolor='black', alpha=0.5)
plt.title('Global')
ax2 = plt.subplot(212, projection=proj)
ax2.stock_img()
ax2.set_extent([x0, x1, y0, y1], box_proj)
plt.title('Zoomed in area')
plt.show()
希望向您展示什么为了实现您的目标地图,上面的代码可能有点复杂,所以为了稍微简化,我将编写代码产生你想要的情节是这样的:
import cartopy.feature
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
ax.set_extent([120, 260, 15, 80], crs=ccrs.PlateCarree())
# add some features to make the map a little more polished
ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.OCEAN)
ax.coastlines('50m')
plt.show()
这是一个很长的答案,希望我不仅回答了这个问题,而且更清楚地说明了地图制作和制图的一些更复杂的细节,以帮助解决您未来可能遇到的任何问题。
干杯,