我收到了以下邮件,并希望确保这个问题的答案是提供给大家:建立一个地图横跨在cartopy日界线
嗨,
我想设置一个简单的纬度经度地图,使用cartopy,它跨越日期线,并在右侧显示北美西部的左侧东亚。下面的谷歌地图大致是我所追求的:
https://maps.google.co.uk/?ll=56.559482,-175.253906&spn=47.333523,133.066406&t=m&z=4
可以这样用Cartopy做什么?
我收到了以下邮件,并希望确保这个问题的答案是提供给大家:建立一个地图横跨在cartopy日界线
嗨,
我想设置一个简单的纬度经度地图,使用cartopy,它跨越日期线,并在右侧显示北美西部的左侧东亚。下面的谷歌地图大致是我所追求的:
https://maps.google.co.uk/?ll=56.559482,-175.253906&spn=47.333523,133.066406&t=m&z=4
可以这样用Cartopy做什么?
好问题。这可能会一次又一次地出现,所以我会在实际上之前一步一步地回答你的具体问题。为了将来的参考,下面的例子是用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()
Unfort unately你想要的情节将需要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()
这是一个长的答案,希望我不仅回答了这个问题,但进行了一些的地图制作更复杂的细节和cartopy更加清晰,以帮助消除您的任何未来的问题。
干杯,
只是为了对这个问题,用户问一个简单的“经纬度”地图评论,并提供了一个谷歌地图,这在我看来是*不*简单的“纬度截图经度“地图。从技术上讲,谷歌地图附在球形墨卡托投影;我的答案认为用户是为了说明目的而设计的,实际上,通过简单的“纬度经度”意味着Equirectangular/PlateCarree。 – pelson