python - Python cartopy 地图,国家以外的剪辑区域(多边形)
问题描述
我用 NaturalEarth 的国家边界创建了一张 Stamen 地形图。现在我想从国家边界之外删除所有数据(在这种情况下是地形)。我该怎么做?
我的例子是瑞士内外可见的地形:
from cartopy.io import shapereader
import cartopy.io.img_tiles as cimgt
import cartopy.crs as ccrs
import geopandas
import matplotlib.pyplot as plt
resolution = '10m'
category = 'cultural'
name = 'admin_0_countries'
shpfilename = shapereader.natural_earth(resolution, category, name)
df = geopandas.read_file(shpfilename)
poly = [df.loc[df['ADMIN'] == 'Switzerland']['geometry'].values[0]]
stamen_terrain = cimgt.Stamen('terrain-background')
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(1, 1, 1, projection=stamen_terrain.crs)
ax.add_geometries(poly, crs=ccrs.PlateCarree(), facecolor='none', edgecolor='r')
exts = [poly[0].bounds[0], poly[0].bounds[2], poly[0].bounds[1], poly[0].bounds[3]]
ax.set_extent(exts, crs=ccrs.Geodetic())
ax.add_image(stamen_terrain, 8)
fig.tight_layout()
plt.show()
如何仅将边界内的地形显示为白色/透明,而将其余的地形显示为白色/透明?
试图玩这个方向,但到目前为止没有成功: https ://scitools.org.uk/cartopy/docs/latest/gallery/logo.html
解决方案
您需要一个蒙版来隐藏图像中不需要的部分。这是一个可运行的代码,演示了获得预期绘图的所有步骤。
from shapely.geometry import Polygon
from cartopy.io import shapereader
import cartopy.io.img_tiles as cimgt
import cartopy.crs as ccrs
import geopandas
import matplotlib.pyplot as plt
def rect_from_bound(xmin, xmax, ymin, ymax):
"""Returns list of (x,y)'s for a rectangle"""
xs = [xmax, xmin, xmin, xmax, xmax]
ys = [ymax, ymax, ymin, ymin, ymax]
return [(x, y) for x, y in zip(xs, ys)]
# request data for use by geopandas
resolution = '10m'
category = 'cultural'
name = 'admin_0_countries'
shpfilename = shapereader.natural_earth(resolution, category, name)
df = geopandas.read_file(shpfilename)
# get geometry of a country
poly = [df.loc[df['ADMIN'] == 'Switzerland']['geometry'].values[0]]
stamen_terrain = cimgt.Stamen('terrain-background')
# projections that involved
st_proj = stamen_terrain.crs #projection used by Stamen images
ll_proj = ccrs.PlateCarree() #CRS for raw long/lat
# create fig and axes using intended projection
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(1, 1, 1, projection=st_proj)
ax.add_geometries(poly, crs=ll_proj, facecolor='none', edgecolor='black')
pad1 = .1 #padding, degrees unit
exts = [poly[0].bounds[0] - pad1, poly[0].bounds[2] + pad1, poly[0].bounds[1] - pad1, poly[0].bounds[3] + pad1];
ax.set_extent(exts, crs=ll_proj)
# make a mask polygon by polygon's difference operation
# base polygon is a rectangle, another polygon is simplified switzerland
msk = Polygon(rect_from_bound(*exts)).difference( poly[0].simplify(0.01) )
msk_stm = st_proj.project_geometry (msk, ll_proj) # project geometry to the projection used by stamen
# get and plot Stamen images
ax.add_image(stamen_terrain, 8) # this requests image, and plot
# plot the mask using semi-transparency (alpha=0.65) on the masked-out portion
ax.add_geometries( msk_stm, st_proj, zorder=12, facecolor='white', edgecolor='none', alpha=0.65)
ax.gridlines(draw_labels=True)
plt.show()
结果图:
和面具:
编辑1
上面的代码适用于单个国家。如果多个连续的国家是我们的新目标,我们需要将它们全部选中并dissolve
放入一个几何体中。只需要修改几行代码。
示例:新的目标国家:['Norway','Sweden','Finland']
要替换的代码行:
poly = [df.loc[df['ADMIN'] == 'Switzerland']['geometry'].values[0]]
要替换的新代码行:
scan3 = df[ df['ADMIN'].isin(['Norway','Sweden', 'Finland']) ]
scan3_dissolved = scan3.dissolve(by='LEVEL')
poly = [scan3_dissolved['geometry'].values[0]]
示例输出映射:
推荐阅读
- rust - 如何在 Rust 中访问系统定时器中断
- java - 为什么我的 ImageButtons 不能为我的滑动益智游戏随机播放?
- excel - 我们如何在没有 MSCOMCT2.OCX 文件的情况下使用 datepicker?
- c++ - Cmake找不到提升窗口
- javascript - 在 *ngfor(Angular) 中插入具有特定样式属性的动态元素
- google-maps - ionic 4 地图在浏览器中工作但在 Andriod 设备中不工作
- javascript - 用户可以在加载页面之前使用开发人员工具控制台取消绑定页面加载事件处理程序吗?
- python-3.x - 一次访问 RDD 中的 200 个文件 pyspark
- operators - 数学等价于双右移和 AND 运算符?
- python - 如何修复 TypeError:不支持的操作数类型?