Python繪制地圖神器folium的新人入門指南
一、簡介
想通過 Python 繪制精美的地圖?想在地圖上自由的設(shè)置各種參數(shù)?想獲得靈活的交互體驗(yàn)?這里就有一款Python 神包滿足你:folium。
folium 建立在 Python 生態(tài)系統(tǒng)的數(shù)據(jù)應(yīng)用能力和 Leaflet.js 庫的映射能力之上,在Python中操作數(shù)據(jù),然后通過 folium 在 Leaflet 地圖中可視化。
folium 相比較于國內(nèi)百度的 pyecharts 靈活性更強(qiáng),能夠自定義繪制區(qū)域,并且展現(xiàn)形式更加多樣化。
附:官方文檔,官方示例,本文 notebook ,完整代碼及數(shù)據(jù)。
二、安裝方法
按照官方的教程即可,如果安裝了 conda ,可以直接
conda install -c conda-forge folium
沒有安裝的話就使用
python3 -m pip install folium
三、主要功能
3.1 各級別地圖
folium 顯示地圖的類為 folium.Map,類的聲明如下
class folium.folium.Map(location=None, width='100%', height='100%', left='0%', top='0%', position='relative', tiles='OpenStreetMap', attr=None, min_zoom=0, max_zoom=18, zoom_start=10, min_lat=-90, max_lat=90, min_lon=-180, max_lon=180, max_bounds=False, crs='EPSG3857', control_scale=False, prefer_canvas=False, no_touch=False, disable_3d=False, png_enabled=False, zoom_control=True, **kwargs)
講幾個(gè)重要的參數(shù)
- location 經(jīng)緯度,list 或者 tuple 格式,順序?yàn)?latitude, longitude
- zoom_start 縮放值,默認(rèn)為 10,值越大比例尺越小,地圖放大級別越大
- tiles 顯示樣式,默認(rèn)*‘OpenStreetMap'*,也就是開啟街道顯示
- crs 地理坐標(biāo)參考系統(tǒng),默認(rèn)為"EPSG3857"
3.1.1 世界地圖
import folium print(folium.__version__) # define the world map world_map = folium.Map() # display world map world_map

3.1.2 國家地圖
# define the national map national_map = folium.Map(location=[35.3, 100.6], zoom_start=4) # display national map national_map

3.1.3 市級地圖
其實(shí)改變地圖顯示就是改變顯示的經(jīng)緯度和縮放比例,省級、市級、縣級用法雷同,這里舉一個(gè)市級的例子為例,如北京市:
# define the city map city_map = folium.Map(location=[39.93, 116.40], zoom_start=10) # display city map city_map

顯示效果確實(shí)是不如百度的😓。
3.2 地圖形式
除了上述正常的地圖顯示外,folium 還提供了非常豐富的多樣化顯示,控制顯示效果的變量是tiles,樣式有OpenStreetMap, Stamen Terrain, Stamen Toner, Mapbox Bright, Mapbox Control Room等等,這里挑選幾個(gè)比較常見的
# define the city map,tiles='Stamen Toner' city_map = folium.Map(location=[39.93, 116.40], zoom_start=10, tiles='Stamen Toner') # display city map city_map
# define the city map, tiles='Stamen Terrain' city_map = folium.Map(location=[39.93, 116.40], zoom_start=10, tiles='Stamen Terrain') # display city map city_map

3.3 在地圖上標(biāo)記
3.3.1 普通標(biāo)記
添加普通標(biāo)記用 Marker
這里可以選擇標(biāo)記的圖案。
bj_map = folium.Map(location=[39.93, 115.40], zoom_start=12, tiles='Stamen Terrain')
folium.Marker(
location=[39.95, 115.33],
popup='Mt. Hood Meadows',
icon=folium.Icon(icon='cloud')
).add_to(bj_map)
folium.Marker(
location=[39.96, 115.32],
popup='Timberline Lodge',
icon=folium.Icon(color='green')
).add_to(bj_map)
folium.Marker(
location=[39.93, 115.34],
popup='Some Other Location',
icon=folium.Icon(color='red', icon='info-sign')
).add_to(bj_map)
bj_map

添加圓形標(biāo)記用 Circle 以及 CircleMarker
bj_map = folium.Map(location=[39.93, 116.40], zoom_start=12, tiles='Stamen Toner')
folium.Circle(
radius=200,
location=[39.92, 116.43],
popup='The Waterfront',
color='crimson',
fill=False,
).add_to(bj_map)
folium.CircleMarker(
location=[39.93, 116.38],
radius=50,
popup='Laurelhurst Park',
color='#3186cc',
fill=True,
fill_color='#3186cc'
).add_to(bj_map)
bj_map

3.3.2 點(diǎn)擊獲取經(jīng)緯度
m = folium.Map(location=[46.1991, -122.1889],tiles='Stamen Terrain',zoom_start=13) m.add_child(folium.LatLngPopup()) m
通過點(diǎn)擊鼠標(biāo)便可以獲取點(diǎn)擊出的經(jīng)緯度。

3.3.3 動態(tài)放置標(biāo)記
m = folium.Map(
location=[46.8527, -121.7649],
tiles='Stamen Terrain',
zoom_start=13
)
folium.Marker(
[46.8354, -121.7325],
popup='Camp Muir'
).add_to(m)
m.add_child(folium.ClickForMarker(popup='Waypoint'))
m

3.4 熱力圖繪制
因?yàn)闆]有實(shí)際的經(jīng)緯度坐標(biāo)數(shù)據(jù),所以這里只能模擬一些位置出來,另外每個(gè)位置還需要一個(gè)數(shù)值作為熱力值。
# generated data
import numpy as np
data = (
np.random.normal(size=(100, 3)) *
np.array([[0.1, 0.1, 0.1]]) +
np.array([[40, 116.5, 1]])
).tolist()
data[:3]
數(shù)據(jù)分布
[[40.04666663299843, 116.59569796477264, 0.9667425547098781], [39.86836537517533, 116.28201445195315, 0.8708549157348728], [40.08123232852134, 116.56884585184197, 0.9104952244371285]]
繪制熱力圖
# HeatMap
from folium.plugins import HeatMap
m = folium.Map([39.93, 116.38], tiles='stamentoner', zoom_start=6)
HeatMap(data).add_to(m)
# m.save(os.path.join('results', 'Heatmap.html'))
m

3.5 密度地圖繪制
folium 不僅可以繪制熱力圖,還可以繪制密度地圖,按照經(jīng)緯度進(jìn)行舉例聚類,然后在地圖中顯示。
from folium.plugins import MarkerCluster
m = folium.Map([39.93, 116.38], tiles='stamentoner', zoom_start=10)
# create a mark cluster object
marker_cluster = MarkerCluster().add_to(m)
# add data point to the mark cluster
for lat, lng, label in data:
folium.Marker(
location=[lat, lng],
icon=None,
popup=label,
).add_to(marker_cluster)
# add marker_cluster to map
m.add_child(marker_cluster)

3.6 自定義地圖區(qū)域
folium 一個(gè)非常有優(yōu)勢的功能就是自定義區(qū)域的繪制了,只要有區(qū)域的邊界數(shù)據(jù),就可以在地圖中以多種多樣的形式展現(xiàn)出來,這里以 folium 官方的美國地圖為例,源數(shù)據(jù)是一個(gè) .json 文件,里面包含了各個(gè)地區(qū)(美國各州)的特征(包括邊界經(jīng)緯度列表、簡稱等),源數(shù)據(jù)傳送門,其數(shù)據(jù)格式如下:

3.6.1 只繪制邊界,不添加數(shù)據(jù)
如果只要求繪制邊界,而不顯示邊界區(qū)域的相關(guān)信息,那么這個(gè)是比較容易的,代碼如下
import json
import requests
# read us-states border
with open("us-states.json") as f:
us_states = json.load(f)
us_map = folium.Map(location=[35.3, -97.6], zoom_start=4)
folium.GeoJson(
us_states,
style_function=lambda feature: {
'fillColor': '#ffff00',
'color': 'black',
'weight': 2,
'dashArray': '5, 5'
}
).add_to(us_map)
#display map
us_map

3.6.2 繪制邊界,添加數(shù)據(jù)
當(dāng)需要在各個(gè)區(qū)域填充數(shù)據(jù)的時(shí)候,這個(gè)稍微麻煩點(diǎn),不僅需要各個(gè)區(qū)域的邊界數(shù)據(jù),還需要各個(gè)區(qū)域的顯示信息,這里同樣也使用官方的美國各州的邊界數(shù)據(jù)為例:
import geopandas as gpd import pandas as pd import folium, branca states = gpd.GeoDataFrame.from_features(us_states, crs=fiona.crs.from_epsg(4326)) states.head()

我們再把收入等數(shù)據(jù)連接到上表中
abbrs = pd.read_json(open("abbrs.json"))
statesmerge = states.merge(abbrs,how='left', left_on='name', right_on='name')
statesmerge['geometry']=statesmerge.geometry.simplify(.05)
income = pd.read_csv("income.csv", dtype={"fips":str})
income['income-2015']=pd.to_numeric(income['income-2015'], errors='coerce')
income.groupby(by="state")[['state','income-2015']].median().head()
statesmerge['medianincome']=statesmerge.merge(income.groupby(by="state")[['state','income-2015']].median(), how='left', left_on='alpha-2', right_on='state')['income-2015']
statesmerge['change']=statesmerge.merge(income.groupby(by="state")[['state','change']].median(), how='left', left_on='alpha-2', right_on='state')['change']
statesmerge.head()

最終繪制出的來的地圖如下:

除此之外,還有很多非常有趣的功能,這里就不一一列舉了,感興趣的可以參考官方的文檔。
四、競品對比與優(yōu)劣勢
國內(nèi)的競品為百度的 pyecharts,和 folium 一樣都可以實(shí)現(xiàn)普通的地圖繪制功能,但是具體使用還有較大的區(qū)別,具體如下表
| 功能 | pyecharts | folium | 備注 |
|---|---|---|---|
| 世界地圖 | 可以 | 可以 | |
| 中文顯示 | 可以 | 部分可以 | folium地圖中標(biāo)尺、文字不能正常顯示,但是嵌入地圖中的中文可以正常顯示 |
| 交互性 | 好 | 好 | |
| 區(qū)(縣)級地圖 | 可以 | 可以 | folium需要區(qū)(縣)邊界數(shù)據(jù) |
| 市級地圖 | 可以 | 可以 | folium需要市邊界數(shù)據(jù) |
| 收費(fèi) | 自定義區(qū)域需要購買百度ak | 自定義區(qū)域功能免費(fèi) | |
| 靈活性 | 好 | 好 | |
| 省級地圖 | 可以 | 可以 | folium需要省邊界數(shù)據(jù) |
| 美觀度 | 好 | 較好 | |
| 自定義區(qū)域 | 部分可以 | 可以 | pyecharts需要百度 ak,folium免費(fèi) |
五、參考資料
[1] https://www.zhihu.com/question/33783546
[2] https://pypi.org/project/folium/
[3] https://nbviewer.jupyter.org/github/python-visualization/folium/tree/master/examples/
到此這篇關(guān)于Python繪制地圖神器folium的文章就介紹到這了,更多相關(guān)Python繪制地圖folium內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 兩個(gè)數(shù)據(jù)庫postgresql對比
這篇文章主要介紹了python 兩個(gè)數(shù)據(jù)庫postgresql對比,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Selenium定位瀏覽器彈窗方法實(shí)例總結(jié)
彈出框是自動化測試中一種常見的元素,這種元素通常是客戶端自帶的,下面這篇文章主要給大家介紹了關(guān)于Selenium定位瀏覽器彈窗方法的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
python中DataFrame常用的描述性統(tǒng)計(jì)分析方法詳解
這篇文章主要介紹了python中DataFrame常用的描述性統(tǒng)計(jì)分析方法詳解,描述性統(tǒng)計(jì)分析是通過圖表或數(shù)學(xué)方法,對數(shù)據(jù)資料進(jìn)行整理、分析,并對數(shù)據(jù)的分布狀態(tài)、數(shù)字特征和隨機(jī)變量之間的關(guān)系進(jìn)行估計(jì)和描述的方法,需要的朋友可以參考下2023-07-07
opencv檢測動態(tài)物體的實(shí)現(xiàn)
本文主要介紹了opencv檢測動態(tài)物體的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07
詳解Python中鍵盤鼠標(biāo)的相關(guān)操作
pyautogui模塊,規(guī)范一點(diǎn)大寫就是PyAutoGUI模塊,是用來實(shí)現(xiàn)自動化腳本的一個(gè)十分得力的小助手。他可以操控鍵盤和鼠標(biāo),可以寫許多工具。本文就來講講如何利用這個(gè)模塊實(shí)現(xiàn)鍵盤鼠標(biāo)的相關(guān)操作,需要的可以參考一下2023-01-01

