姓名:韓宜真
學號:17020120095
轉載自:https://mp.weixin.qq.com/s/8vnS5wr8AiexU-06RfGGIA
【嵌牛導讀】本文介紹一種Python-geopandas包繪制空間地圖的方法。
【嵌牛鼻子】geopandas
【嵌牛提問】如何用python繪制地圖呢哑诊?
【嵌牛正文】
geopandas 讀取中國地圖文件
geopandas提供了非常方便的read_file()方法用于讀取geojson文件如筛,我們直接進行默認投影(WGS84)的繪制,代碼如下:
file?=?r"中國省級地圖GS(2019)1719號.geojson"
nine?=?r"九段線GS(2019)1719號.geojson"
china_main?=?gpd.read_file(file)
china_nine?=?gpd.read_file(nine)
fig,?ax?=?plt.subplots(figsize=(12,?8),dpi=80)
ax?=?china_main.plot(ax=ax)
ax?=?china_nine.plot(ax=ax)
可視化結果如下:
我們進行投影轉換(epsg=2343)和進行一些簡單的設置,代碼如下:
fig,?ax?=?plt.subplots(figsize=(12,?8),dpi=80)
ax?=?china_main.geometry.to_crs(epsg=2343).plot(fc="white",ec="black",ax=ax)
ax?=?china_nine.geometry.to_crs(epsg=2343).plot(ec="black",ax=ax)
這里注意to_crs(epsg=2343)?就可以進行投影轉換了。
繪圖數(shù)據(jù)操作
接下來,我們將我們要繪制的數(shù)據(jù)讀取酪耕、轉換并繪制在地圖上,數(shù)據(jù)預覽如下:
我們使用如下代碼將其轉換成具有地理信息的geopandas 格式數(shù)據(jù):
scattergdf?=?gpd.GeoDataFrame(
scatter,?geometry=gpd.points_from_xy(scatter.lon,?scatter.lat),
crs="EPSG:4326")
scattergdf.head()
結果如下:
接下來再將其轉換成 epsg=2343 投影下的數(shù)據(jù):
scattergdf_2343?=?scattergdf.to_crs(epsg=2343,?inplace=True)
以上就完成的數(shù)據(jù)的處理操作了
地圖可視化繪制
直接給出繪圖代碼轨淌,然后再進行解釋迂烁。主要代碼如下:
fig,?ax?=?plt.subplots(figsize=(8,5),dpi=200,)
plt.rcParams['font.family']?=?['Times?New?Roman']
ax?=?china_main.geometry.to_crs(epsg=2343).plot(fc="white",ec="black",linewidth=.8,ax=ax)
ax?=?china_nine.geometry.to_crs(epsg=2343).plot(color="gray",linewidth=.9,ax=ax)
forloc,?size,class_nameinzip(scattergdf_2343.geometry.representative_point(),\
scattergdf_2343["data"],scattergdf_2343["class"]):
ax.scatter(loc.x,loc.y,s=10*size,fc=class_color[class_name],ec="black",lw=.5,zorder=2)
#添加刻度線
forspinein['top','left',"bottom","right"]:
ax.spines[spine].set_color("none")
ax.set_xlim(china_nine_2343.geometry[0].x-500000,?china_nine_2343.geometry[1].x)
ax.set_ylim(china_nine_2343.geometry[0].y,?china_nine_2343.geometry[1].y)
ax.set_xticks([])
ax.set_yticks([])
#單獨繪制圖例散點
ax.scatter([],?[],?c='#E21C21',?s=30,??label='cluster1',ec="black",lw=.5)
ax.scatter([],?[],?c='#3A7CB5',?s=30,??label='cluster2',ec="black",lw=.5)
ax.scatter([],?[],?c='#51AE4F',?s=30,??label='cluster3',ec="black",lw=.5)
ax.scatter([],?[],?c='white',?s=1*10,label='1',?edgecolor='black',lw=.5)
ax.scatter([],?[],?c='white',?s=2*10,label='2',?edgecolor='black',lw=.5)
ax.scatter([],?[],?c='white',?s=3*10,label='3',?edgecolor='black',lw=.5)
ax.scatter([],?[],?c='white',?s=4*10,label='4',?edgecolor='black',lw=.5)
ax.scatter([],?[],?c='white',?s=5*10,label='5',?edgecolor='black',lw=.5)
ax.legend(frameon=False,ncol=8,loc="upper?center",
fontsize=9,columnspacing=.2)
ax.text(.91,-0.02,'\nVisualization?by?DataCharm',transform?=?ax.transAxes,
ha='center',?va='center',fontsize?=?6,color='black')
#添加南海小地圖????
ax_child?=?fig.add_axes([0.688,?0.125,?0.2,?0.2])
ax_child?=?china_main.geometry.to_crs(epsg=2343).plot(ax=ax_child,
fc="white",
ec="black",)
ax_child?=?china_nine.geometry.to_crs(epsg=2343).plot(ax=ax_child,
color="gray",
linewidth=.9,
)
forloc,?size,class_nameinzip(scattergdf_2343.geometry.representative_point(),\
scattergdf_2343["data"],scattergdf_2343["class"]):
ax_child.scatter(loc.x,loc.y,s=10*size,fc=class_color[class_name],ec="black",lw=.5,zorder=2)
ax_child.set_xlim(china_nine_2343.geometry[2].x,?china_nine_2343.geometry[3].x)
ax_child.set_ylim(china_nine_2343.geometry[2].y,?china_nine_2343.geometry[3].y)
#?移除子圖坐標軸刻度看尼,
ax_child.set_xticks([])
ax_child.set_yticks([])
add_axes() 添加南海小地圖
#添加南海小地圖????
ax_child?=?fig.add_axes([0.688,?0.125,?0.2,?0.2])
ax_child?=?china_main.geometry.to_crs(epsg=2343).plot(ax=ax_child,
fc="white",
ec="black",)
ax_child?=?china_nine.geometry.to_crs(epsg=2343).plot(ax=ax_child,
color="gray",
linewidth=.9,
)
forloc,?size,class_nameinzip(scattergdf_2343.geometry.representative_point(),\
scattergdf_2343["data"],scattergdf_2343["class"]):
ax_child.scatter(loc.x,loc.y,s=10*size,fc=class_color[class_name],ec="black",lw=.5,zorder=2)
ax_child.set_xlim(china_nine_2343.geometry[2].x,?china_nine_2343.geometry[3].x)
ax_child.set_ylim(china_nine_2343.geometry[2].y,?china_nine_2343.geometry[3].y)
#?移除子圖坐標軸刻度,
ax_child.set_xticks([])
ax_child.set_yticks([])
可以發(fā)現(xiàn)盟步,除了顯示范圍的不同外藏斩,其他的和繪制主題部分的代碼一致。
單獨添加圖例
#單獨繪制圖例散點
ax.scatter([],?[],?c='#E21C21',?s=30,??label='cluster1',ec="black",lw=.5)
ax.scatter([],?[],?c='#3A7CB5',?s=30,??label='cluster2',ec="black",lw=.5)
ax.scatter([],?[],?c='#51AE4F',?s=30,??label='cluster3',ec="black",lw=.5)
ax.scatter([],?[],?c='white',?s=1*10,label='1',?edgecolor='black',lw=.5)
ax.scatter([],?[],?c='white',?s=2*10,label='2',?edgecolor='black',lw=.5)
ax.scatter([],?[],?c='white',?s=3*10,label='3',?edgecolor='black',lw=.5)
ax.scatter([],?[],?c='white',?s=4*10,label='4',?edgecolor='black',lw=.5)
ax.scatter([],?[],?c='white',?s=5*10,label='5',?edgecolor='black',lw=.5)
ax.legend(frameon=False,ncol=8,loc="upper?center",
fontsize=9,columnspacing=.2)
這部分還是為了更好的定制化圖例却盘,希望大家可以掌握狰域。
最終,我們的可視化效果如下:
注:該數(shù)據(jù)只限于練習交流黄橘,請勿用于科研兆览、出版使用。
總結
本期推文使用了Python-geopandas進行了中國地圖的繪制,講解了數(shù)據(jù)標記塞关,投影轉換等內容拓颓。但需指出的是:
geopandas 的安裝較為麻煩,建議使用?conda install --channel conda-forge geopandas?進行安裝描孟。
Python 繪制空間可視化還是存在部分問題(無法較容易的添加如比例尺、指北針等空間繪圖元素)砰左,也在進一步完善過程中匿醒。