python - 使用 shapefile 或 geopandas 绘制蒙面南极洲

标签 python shapefile matplotlib-basemap geopandas

我正在尝试绘制南极洲周围的数据,同时掩盖该大陆。当我使用 basemap 并且它可以选择使用 map.fillContinues() 轻松掩盖大陆时,basemap 考虑的大陆包括冰架,我不想掩盖它。

我尝试使用在互联网上找到的代码中的geopandas。这是可行的,除了海岸线在我认为是南极洲多边形的开始/结束处产生了一条不需要的线:

import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
import geopandas as gpd
import shapely
from descartes import PolygonPatch

lats = np.arange(-90,-59,1)
lons = np.arange(0,361,1)
X, Y = np.meshgrid(lons, lats)
data = np.random.rand(len(lats),len(lons))

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))

fig=plt.figure(dpi=150)
ax = fig.add_subplot(111)

m = Basemap(projection='spstere',boundinglat=-60,lon_0=180,resolution='i',round=True)  
xi, yi = m(X,Y)

cf = m.contourf(xi,yi,data)

patches = []
selection = world[world.name == 'Antarctica']
for poly in selection.geometry:
    if poly.geom_type == 'Polygon':
        mpoly = shapely.ops.transform(m, poly)
        patches.append(PolygonPatch(mpoly))
    elif poly.geom_type == 'MultiPolygon':
        for subpoly in poly:
            mpoly = shapely.ops.transform(m, poly)
            patches.append(PolygonPatch(mpoly))
    else:
        print(poly, 'blah')
ax.add_collection(PatchCollection(patches, match_original=True,color='w',edgecolor='k'))

Geopandas output

当我尝试使用其他 shapefile 时,例如可以从 Natural Earth Data 免费下载的 land 形状文件,也会出现同样的行。 。所以我在 QGIS 中编辑了这个 shapefile 以删除南极洲的边界。现在的问题是我不知道如何屏蔽 shapefile 内的所有内容(并且也找不到如何做到这一点)。我还尝试通过设置 linewidth=0 并将之前的代码与 geopandas 结合起来,并在顶部添加我创建的 shapefile。问题是它们并不完全相同:

Bad borders when using geopandas and shapefile

关于如何使用 shapefile 或使用 geopandas 但不使用线条进行 mask 有什么建议吗?

编辑:使用 Thomas Khün 之前的 answer使用我编辑的形状文件会生成一个屏蔽良好的南极洲/大陆,但海岸线超出了 map 的圆形边缘:

outside edges

我上传了here我使用的编辑后的形状文件,但它是 Natural Earth Data 50m land shapefile没有线。

最佳答案

这里是如何实现您想要的目标的示例。我基本上是跟着Basemap example如何处理 shapefiles 并添加了一些 shapely magic将轮廓限制在 map 边界内。请注意,我首先尝试从 ax.patches 中提取 map 轮廓,但不知何故不起作用,因此我定义了一个半径为boundinglat 的圆并进行了转换它使用 basemap 坐标转换功能。

import numpy as np

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon

import shapely
from shapely.geometry import Polygon as sPolygon

boundinglat = -40 
lats = np.arange(-90,boundinglat+1,1)
lons = np.arange(0,361,1)
X, Y = np.meshgrid(lons, lats)
data = np.random.rand(len(lats),len(lons))

fig, ax = plt.subplots(nrows=1, ncols=1, dpi=150)

m = Basemap(
    ax = ax,
    projection='spstere',boundinglat=boundinglat,lon_0=180,
    resolution='i',round=True
)  
xi, yi = m(X,Y)

cf = m.contourf(xi,yi,data)

#adjust the path to the shapefile here:
result = m.readshapefile(
    'shapefiles/AntarcticaWGS84_contorno', 'antarctica',
    zorder = 10, color = 'k', drawbounds = False)

#defining the outline of the map as shapely Polygon:
rim = [np.linspace(0,360,100),np.ones(100)*boundinglat,]
outline = sPolygon(np.asarray(m(rim[0],rim[1])).T)

#following Basemap tutorial for shapefiles
patches = []
for info, shape in zip(m.antarctica_info, m.antarctica):
    #instead of a matplotlib Polygon, create first a shapely Polygon
    poly = sPolygon(shape)
    #check if the Polygon, or parts of it are inside the map:
    if poly.intersects(outline):
        #if yes, cut and insert
        intersect = poly.intersection(outline)        
        verts = np.array(intersect.exterior.coords.xy)
        patches.append(Polygon(verts.T, True))

ax.add_collection(PatchCollection(
    patches, facecolor= 'w', edgecolor='k', linewidths=1., zorder=2
))

plt.show()

结果如下所示:

the result of the above code

希望这有帮助。

关于python - 使用 shapefile 或 geopandas 绘制蒙面南极洲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50378688/

相关文章:

python - 在列表中查找特定模式

python - pyodbc 无法连接到数据库,但 IBM Data Studio 使用相同的凭证连接

r - 在多个绘图中将 shapefile 叠加在栅格上

Python Matplotlib 函数动画

r - R中的Shapefile到光栅转换?

postgresql - 将 Shapefile 导入 Postgres

python - 在 Matplotlib 中校正轨迹

python - 在matplotlib中安装Basemap时出现问题

numpy - 准备数据以在 Matplotlib 的 basemap 中绘制等高线

python: 无法打开文件 get-pip.py 错误 2] 没有这样的文件或目录