我试图通过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()
目前没有回答
相关问题 更多 >
编程相关推荐