pel*_*son 11 matplotlib cartopy
我收到了以下电子邮件,并希望确保每个人都能获得这个问题的答案:
嗨,
我想设置一个简单的纬度经度地图,使用纸板,横跨日期线,并在左侧显示东亚,右侧显示北美西部.以下谷歌地图大致是我所追求的:
https://maps.google.co.uk/?ll=56.559482,-175.253906&spn=47.333523,133.066406&t=m&z=4

这可以用Cartopy完成吗?
pel*_*son 29
好问题.这可能是东西,将再次拿出时间和时间,所以我将通过这一步一步的前居然回答您的具体问题.为了将来参考,以下示例使用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()
Run Code Online (Sandbox Code Playgroud)

您可以在此地图上绘制的任何单个矩形在法律上都可以是放大区域(这里有一些稍高级的代码,但图片值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()
Run Code Online (Sandbox Code Playgroud)

不幸的是,你想要的情节需要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()
Run Code Online (Sandbox Code Playgroud)

因此,无法使用标准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()
Run Code Online (Sandbox Code Playgroud)

希望将告诉您什么是你必须做,以实现你的目标的地图,上面的代码可能有点复杂,以实现自己的目标,所以要稍微简化的代码,我会写来生成所需会是这样的情节:
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()
Run Code Online (Sandbox Code Playgroud)

这是一个很长的答案,希望我不仅回答了这个问题,而且使一些更为复杂的地图制作和图谱细节更加清晰,以帮助解决您可能遇到的任何未来问题.
干杯,
| 归档时间: |
|
| 查看次数: |
2437 次 |
| 最近记录: |