首頁 > 軟體

Python繪製地圖神器folium的新人入門指南

2021-05-23 16:01:48

一、簡介

想通過 Python 繪製精美的地圖?想在地圖上自由的設定各種引數?想獲得靈活的互動體驗?這裡就有一款Python 神包滿足你:folium

folium 建立在 Python 生態系統的資料應用能力和 Leaflet.js 庫的對映能力之上,在Python中運算元據,然後通過 folium 在 Leaflet 地圖中視覺化。

folium 相比較於國內百度的 pyecharts 靈活性更強,能夠自定義繪製區域,並且展現形式更加多樣化。

附:官方檔案官方範例本文 notebook完整程式碼及資料

二、安裝方法

按照官方的教學即可,如果安裝了 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)

講幾個重要的引數

  • location 經緯度,list 或者 tuple 格式,順序為 latitude, longitude
  • zoom_start 縮放值,預設為 10,值越大比例尺越小,地圖放大級別越大
  • tiles 顯示樣式,預設*‘OpenStreetMap'*,也就是開啟街道顯示
  • crs 地理座標參考系統,預設為"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 市級地圖

其實改變地圖顯示就是改變顯示的經緯度和縮放比例,省級、市級、縣級用法雷同,這裡舉一個市級的例子為例,如北京市:

# define the city map
city_map = folium.Map(location=[39.93, 116.40], zoom_start=10)
# display city map
city_map

顯示效果確實是不如百度的😓。

3.2 地圖形式

除了上述正常的地圖顯示外,folium 還提供了非常豐富的多樣化顯示,控制顯示效果的變數是tiles,樣式有OpenStreetMap, Stamen Terrain, Stamen Toner, Mapbox Bright, Mapbox Control Room等等,這裡挑選幾個比較常見的

# 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 在地圖上標記

3.3.1 普通標記

新增普通標記用 Marker

這裡可以選擇標記的圖案。

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

新增圓形標記用 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 點選獲取經緯度

m = folium.Map(location=[46.1991, -122.1889],tiles='Stamen Terrain',zoom_start=13)

m.add_child(folium.LatLngPopup())

m

通過點選滑鼠便可以獲取點選出的經緯度。

3.3.3 動態放置標記

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 熱力圖繪製

因為沒有實際的經緯度座標資料,所以這裡只能模擬一些位置出來,另外每個位置還需要一個數值作為熱力值。

# 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]

資料分佈

[[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 不僅可以繪製熱力圖,還可以繪製密度地圖,按照經緯度進行舉例聚類,然後在地圖中顯示。

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 自定義地圖區域

folium 一個非常有優勢的功能就是自定義區域的繪製了,只要有區域的邊界資料,就可以在地圖中以多種多樣的形式展現出來,這裡以 folium 官方的美國地圖為例,源資料是一個 .json 檔案,裡面包含了各個地區(美國各州)的特徵(包括邊界經緯度列表、簡稱等),源資料傳送門,其資料格式如下:

3.6.1 只繪製邊界,不新增資料

如果只要求繪製邊界,而不顯示邊界區域的相關資訊,那麼這個是比較容易的,程式碼如下

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 繪製邊界,新增資料

當需要在各個區域填充資料的時候,這個稍微麻煩點,不僅需要各個區域的邊界資料,還需要各個區域的顯示資訊,這裡同樣也使用官方的美國各州的邊界資料為例:

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()

我們再把收入等資料連線到上表中

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()

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

除此之外,還有很多非常有趣的功能,這裡就不一一列舉了,感興趣的可以參考官方的檔案。

四、競品對比與優劣勢

國內的競品為百度的 pyecharts,和 folium 一樣都可以實現普通的地圖繪製功能,但是具體使用還有較大的區別,具體如下表

功能 pyecharts folium 備註
世界地圖 可以 可以
中文顯示 可以 部分可以 folium地圖中標尺、文字不能正常顯示,但是嵌入地圖中的中文可以正常顯示
互動性
區(縣)級地圖 可以 可以 folium需要區(縣)邊界資料
市級地圖 可以 可以 folium需要市邊界資料
收費 自定義區域需要購買百度ak 自定義區域功能免費
靈活性
省級地圖 可以 可以 folium需要省邊界資料
美觀度 較好
自定義區域 部分可以 可以 pyecharts需要百度 ak,folium免費

五、參考資料

[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/

到此這篇關於Python繪製地圖神器folium的文章就介紹到這了,更多相關Python繪製地圖folium內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com