使用笛卡尔和 matplotlib 绘制 shapefile - ValueError

问题描述

我正在尝试通过 matplotlib 绘制一个 shapefile(NUTS_BN_01M_2021_3035_LEVL_2.shp 从这里 https://ec.europa.eu/eurostat/web/gisco/geodata/reference-data/administrative-units-statistical-units/nuts)。

在我自己尝试了几次之后,我在网上找到了一个教程 (https://www.wemcouncil.org/wp/tech-blog-7-plot-a-map-with-eurostat-nuts2-regions-in-7-easy-steps/)。但我总是收到错误

File "C:\Users\alexa\anaconda3\lib\site-packages\descartes\patch.py",line 60,in polygonPath
"A polygon or multi-polygon representation is required")
ValueError: A polygon or multi-polygon representation is required

错误来自

tt = polygonPatch(poly_geo,fc='#ffffff',ec='#000000',alpha=0.5,zorder=2 )

我尝试将 poly_geo 放入列表,但没有成功。没有这条线的代码工作得很好,我尝试了一下,因为我确实读到空多边形可能会导致问题,但随后绘制了一个空地图。在 anaconda 环境中运行 Python 3.7。

对这里的问题有什么建议吗?

到目前为止我的代码

# import packages
import geopandas as gpd
import matplotlib.pyplot as plt
from descartes import polygonPatch
import shapefile
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from matplotlib.offsetBox import AnchoredText
import itertools

nuts=gpd.read_file('C://github_repos/codeschnipsel/Mapplots/data/NUTS_BN_01M_2021_3035_LEVL_2.shp')

# use representitive_point method to obtain point from within each shapefile
# creates new column 'coords' containing the representitive points
nuts['coords'] = nuts['geometry'].apply(lambda x: x.representative_point().coords[:])
nuts['coords'] = [coords[0] for coords in nuts['coords']]

sf=shapefile.Reader("C://github_repos/codeschnipsel/Mapplots/data/NUTS_BN_01M_2021_3035_LEVL_2.shp")
def main():
    fig = plt.figure(figsize=(80,40)) 
    
    ax = fig.add_subplot(1,1,projection=ccrs.PlateCarree())
    
    #hi res polygons for land,sea etc
    ax.coastlines(resolution='10m',color='black',linewidth=1)
    ax.natural_earth_shp(name='land',resolution='10m',category='physical')
    ax.natural_earth_shp(name='ocean',resolution='50m',category='physical',facecolor='lightblue')

    
    for poly in sf.shapes():
        poly_geo=poly.__geo_interface__
        tt = polygonPatch(poly_geo,zorder=2 )
        ax.add_patch(tt)
    ax.axis('scaled')

    # annotate plot with NUTS_ID 
    for idx,row in nuts.iterrows():
        plt.annotate(s=row['NUTS_BN_ID'],xy=row['coords'],horizontalalignment='center')

    # adjust plot domain to focus on EU region
    plt.xlim(-25,47)
    plt.ylim(30,73)     

    # Add a text annotation for the license information to the
    # the bottom right corner.
    text = AnchoredText(r'$\mathcircled{{c}}$ Luke Sanger - WEMC (2020)',loc=4,prop={'size': 12},frameon=True)
    ax.add_artist(text)
    plt.show()

if __name__ == '__main__':
    main()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)