最近正好在學(xué)空間數(shù)據(jù)處理,這次更一下用python如何畫出好看的地圖 下面主要是用
folium
poltly
geopandas+matplotlib
三種方式繪制地圖
1.folium
import folium
import pandas as pd
#輸入上海經(jīng)緯度,尺度
latitude = 31.2
longitude = 121.5
sh_map = folium.Map(location=[latitude, longitude], zoom_start=10)
sh_map
默認(rèn)為’OpenStreetMap’風(fēng)格,我們還可以選擇’Stamen Terrain’, 'Stamen Toner’等
sh_map = folium.Map(location=[latitude, longitude], zoom_start=10,tiles='Stamen Toner')
sh_map
有了底圖把帶有經(jīng)緯度的數(shù)據(jù)點映射上去,這里用上次上海poi中的火鍋數(shù)據(jù) 把火鍋店數(shù)據(jù)放到地圖上
# 創(chuàng)建特征組
hotpots = folium.map.FeatureGroup()
# Loop through the 200 crimes and add each to the incidents feature group
for lat, lng, in zip(data.lat, data.lon):hotpots.add_child(folium.CircleMarker([lat, lng],radius=7, # define how big you want the circle markers to becolor='yellow',fill=True,fill_color='red',fill_opacity=0.4))# 把火鍋特征組放到上海地圖上
sh_map =folium.Map(location=[latitude, longitude], zoom_start=10)
sh_map.add_child(hotpots)
點太多看不出什么,我們下面只放嘉定區(qū)的數(shù)據(jù) 我們可以繼續(xù)添加火鍋店名字信息并標(biāo)注在上圖
latitudes = list(datas.lat)
longitudes = list(datas.lon)
labels = list(datas.name)
for lat, lng, label in zip(latitudes, longitudes, labels):folium.Marker([lat, lng], popup=label).add_to(sh_map)
sh_map
最后我們需要繪制每個區(qū)的火鍋數(shù)量的Choropleth Map,不同顏色代表火鍋數(shù)量 首先讀取上海行政區(qū)geojson文件 統(tǒng)計各個區(qū)火鍋數(shù)量
hots=data.groupby('adname',as_index=False).agg({'name':"count"})
hots.columns=['district','num']
hots
開始繪制Choropleth Map, 下面key_on='feature.properties.name’是因為我們這里下載的上海geojson中name對應(yīng)于行政區(qū),這個根據(jù)具體數(shù)據(jù)而定
#輸入上海經(jīng)緯度,尺度
latitude = 31.2
longitude = 121.5
map = folium.Map(location=[latitude, longitude], zoom_start=12)
folium.Choropleth(geo_data=geo_data,data=hots,columns=['district','num'],key_on='feature.properties.name',#fill_color='red',fill_color='YlOrRd',fill_opacity=0.7,line_opacity=0.2,highlight=True,legend_name='Hotpot Counts in Shanghai'
).add_to(map)
map
浦東新區(qū)一馬當(dāng)先,嘉定區(qū)榜上有名
2.poltly
用poltly畫Choropleth Map跟folium很類似,這里直接繼續(xù)用前面處理好的數(shù)據(jù)
import plotly.express as px
import plotly.graph_objs as go
latitude = 31.2
longitude = 121.5
fig = px.choropleth_mapbox(data_frame=hots,geojson=geo_data,color='num',locations="district",featureidkey="properties.name",mapbox_style="carto-positron",color_continuous_scale='viridis',center={"lat": latitude, "lon": longitude},zoom=7.5,
)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
設(shè)置mapbox_style="carto-darkmatter"換一種風(fēng)格
3.geopandas+matplotlib
先利用geopandas繪制出各行政區(qū)輪廓
import matplotlib.pyplot as plt
import matplotlib as mpl
# 中文和負(fù)號的正常顯示
mpl.rcParams['font.sans-serif'] = ['Times New Roman']
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
# 裁剪上海shape
fig, ax = plt.subplots(figsize=(20, 10))
ax=geo_data.plot(ax=ax,facecolor='grey',edgecolor='white',linestyle='--',alpha=0.8)
ax.axis('off') # 移除坐標(biāo)軸
將統(tǒng)計的各個區(qū)的火鍋店數(shù)量與geo_data合并
need_data=pd.merge(geo_data,hots[['district','num']],left_on='name',right_on='district')
need_data
此時數(shù)據(jù)已經(jīng)是dataframe,不是需要的geodataframe了,所以需要繼續(xù)轉(zhuǎn)換一下
need_data = gpd.GeoDataFrame(need_data)
need_data.geom_type
可以看到這個時候need_data已經(jīng)是geodataframe類型了
fig, ax = plt.subplots(figsize=(20, 10))
need_data.plot('num', cmap='OrRd',ax=ax)
ax.axis('off') # 移除坐標(biāo)軸
cmap = mpl.cm.get_cmap('OrRd')
norm = mpl.colors.Normalize(min(need_data['num']), max(need_data['num']))
fcb = fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap),ax=ax)
ax=geo_data.plot(ax=ax,facecolor='grey',edgecolor='white',linestyle='--',alpha=0.2)
ax.set_title('Hotpot Count in Shanghai', fontsize=20)
不熟悉上海的人是看不出來各個區(qū)的,這里可以繼續(xù)加行政區(qū)標(biāo)注
fig, ax = plt.subplots(figsize=(20, 10))
need_data.plot('num', cmap='OrRd',ax=ax)
for idx, _ in enumerate(need_data.geometry.representative_point()):# 提取行政區(qū)名稱region = need_data.loc[idx, 'name']ax.text(_.x, _.y, region, ha="center", va="center", size=8)
ax.axis('off') # 移除坐標(biāo)軸
cmap = mpl.cm.get_cmap('OrRd')
norm = mpl.colors.Normalize(min(need_data['num']), max(need_data['num']))
fcb = fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap),ax=ax)
ax=geo_data.plot(ax=ax,facecolor='grey',edgecolor='white',linestyle='--',alpha=0.2)
ax.set_title('Hotpot Count in Shanghai', fontsize=20)
本文的notebook及數(shù)據(jù)可公眾號后臺回復(fù)地圖 獲得
總結(jié)
以上是生活随笔 為你收集整理的用python如何画出好看的地图 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。