使用笛卡尔和matplotlib值错误打印形状文件

2024-05-16 10:07:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过matplotlib绘制一个形状文件(NUTS_BN_01M_2021_3035_level_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 env的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, 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, fc='#ffffff', ec='#000000', alpha=0.5, 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()

Tags: theinimportforaspltcoordsax