這可能是 Python裡最強的繪製地圖神器

2021-02-25 Python職場圈

作者:錢魏Way 
原文:https://www.biaodianfu.com/folium.html

大家好,我是明哥。

今天給大家介紹一個非常 NB 的Python 庫,專門用來繪製地圖的,它叫 Folium 。

1. Folium簡介

Folium是一個基於leaflet.js的Python地圖庫,其中,Leaflet是一個非常輕的前端地圖可視化庫。即可以使用Python語言調用Leaflet的地圖可視化能力。它不單單可以在地圖上展示數據的分布圖,還可以使用Vincent/Vega在地圖上加以標記。Folium可以讓你用Python強大生態系統來處理數據,然後用Leaflet地圖來展示。

Folium中有許多來自OpenStreetMap、MapQuest Open、MapQuestOpen Aerial、Mapbox和Stamen的內建地圖元件,而且支持使用Mapbox或Cloudmade的API密鑰來定製個性化的地圖元件。Folium支持GeoJSON和TopoJSON兩種文件格式的疊加,也可以將數據連接到這兩種文件格式的疊加層,最後可使用color-brewer配色方案創建分布圖。

2. Folium的使用地圖的生成img

folium.folium.Map()詳解

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 (tuple or list, default None):緯度和經度

width (pixel int or percentage string (default: 『100%』)):地圖寬度

height (pixel int or percentage string (default: 『100%』)):地圖高度

tiles (str, default 『OpenStreetMap』) :瓦片名稱或使用TileLayer classass.

min_zoom (int, default 0):地圖可縮放的最小級別

max_zoom (int, default 18):地圖可縮放的最大級別

zoom_start (int, default 10) :地圖的初始縮放級別

attr (string, default None):當使用自定義瓦片時,傳入自定義瓦片的名詞

crs (str, default 『EPSG3857』) :投影坐標系標識

EPSG3857: Web墨卡託投影后的平面地圖,坐標單位為米。大部分國外地圖使用的時該標準。

EPSG4326: Web墨卡託投影后的平面地圖,但仍然使用WGS84的經度、緯度表示坐標。

EPSG3395: 墨卡託投影,主要用於航海圖

Simple: 簡單的x,y匹配,用於自定義瓦片(比如遊戲地圖)

control_scale (bool, default False) :是否在地圖上顯示縮放標尺

prefer_canvas (bool, default False):強制使用Canvas渲染

no_touch (bool, default False) :是否允許觸摸事件

disable_3d (bool, default False) :強制使用CSS 3D效果

zoom_control (bool, default True) :是否要限制zoom操作

**kwargs:Leaflets地圖類的其他參數: https://leafletjs.com/reference-1.5.1.html#map

「tiles」參數可選值:

「OpenStreetMap」

「Mapbox Bright」 (Limited levels of zoom for free tiles)

「Mapbox Control Room」 (Limited levels of zoom for free tiles)

「Stamen」 (Terrain, Toner, and Watercolor)

「Cloudmade」 (Must pass API key)

「Mapbox」 (Must pass API key)

「CartoDB」 (positron and dark_matter)

「tiles」的自定義設置:

img

地球上同一個地理位置的經緯度,在不同的坐標系中,會有少量偏移,國內目前常見的坐標系主要分為三種:

地球坐標系——WGS84:常見於GPS設備,Google地圖等國際標準的坐標體系。

火星坐標系——GCJ-02:中國國內使用的被強制加密後的坐標體系,高德坐標就屬於該種坐標體系。

百度坐標系——BD-09:百度地圖所使用的坐標體系,是在火星坐標系的基礎上又進行了一次加密處理。

所以在設置「tiles」時需要考慮目前手中得經緯度屬於那種坐標系。

由於投影坐標系中沒有GCJ-02和BD-09對應的標識,所以在自定義瓦片時主要經緯度能匹配上,crs中的設置可保持不變。更多詳情介紹請看:瓦片坐標系學習

如果需要將地圖保存,只需執行:m.save(「map.html」) 即可。

添加點、線、面要素

添加點

import folium
m = folium.Map(location=[39.917834, 116.397036], zoom_start=13, width='50%',height='50%', zoom_control='False',
               tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}&ltype=6',attr='AutoNavi')

tooltip ='請點擊我查看該點信息'
folium.Marker([39.937282,116.403187], popup='南鑼鼓巷',tooltip=tooltip).add_to(m)
folium.Marker([39.917834,116.397036], popup='故宮',tooltip=tooltip).add_to(m)
folium.Marker([39.928614,116.391746], popup='北海公園', tooltip=tooltip, icon=folium.Icon(color='red')).add_to(m)
folium.Marker([39.942143,116.382590], popup='後海公園', tooltip=tooltip, icon=folium.Icon(color='green', prefix='fa', icon='taxi')).add_to(m)

m


img

Folium.Icon類可以設置color, icon_color, icon, angle, prefix這5個參數:

color的可選項包括:[『red』, 『blue』, 『green』, 『purple』, 『orange』, 『darkred』, 『lightred』, 『beige』, 『darkblue』, 『darkgreen』, 『cadetblue』, 『darkpurple』, 『white』, 『pink』, 『lightblue』, 『lightgreen』, 『gray』, 『black』, 『lightgray』] ,或者HTML顏色代碼

icon_color同上

icon可以在Font-Awesome網站中找到對應的名字,並設置prefix參數為』fa』

angle以度為單位設置

其他:

m.add_child(folium.LatLngPopup()) #顯示滑鼠點擊點經緯度
m.add_child(folium.ClickForMarker(popup='Waypoint')) # 將滑鼠點擊點添加到地圖上

添加圓

folium.Circle(
    radius=300,
    location=[39.928614,116.391746],
    popup='北海公園',
    color='crimson',
    fill=False,
).add_to(m)
folium.CircleMarker(
    location=[39.942143,116.382590],
    radius=50,
    popup='後海公園',
    color='#3186cc',
    fill=True,
    fill_color='#3186cc'
).add_to(m)


img

Circle和CircleMarker的不同:CircleMarker的radius一個單位是像素,Circle的一個單位時米

添加線段

folium.PolyLine([
    [39.917834,116.397036],
    [39.928614,116.391746],
    [39.937282,116.403187],
    [39.942143,116.382590]
],color='red').add_to(m)


img

添加多邊形

folium.Marker([39.917834,116.397036], popup='故宮').add_to(m)
folium.Marker([39.928614,116.391746], popup='北海公園').add_to(m)
folium.Marker([39.937282,116.403187], popup='南鑼鼓巷').add_to(m)
folium.Marker([39.942143,116.382590], popup='後海公園').add_to(m)

folium.Polygon([
    [39.917834,116.397036],
    [39.928614,116.391746],
    [39.942143,116.382590],
    [39.937282,116.403187],
],color='blue', weight=2, fill=True, fill_color='blue', fill_opacity=0.3).add_to(m)


imgFolium的其他高級應用

在地圖上顯示前200條犯罪數據

import folium
import pandas as pd

san_map = folium.Map(location=[37.77, -122.42], zoom_start=12,width='50%',height='50%')

# cdata = pd.read_csv('https://cocl.us/sanfran_crime_dataset')
cdata = pd.read_csv('Police_Department_Incidents_-_Previous_Year__2016_.csv') #犯罪數據,包含犯罪所在經緯度

# get the first 200 crimes in the cdata
limit = 200
data = cdata.iloc[0:limit, :]
# Instantiate a feature group for the incidents in the dataframe
incidents = folium.map.FeatureGroup()
# Loop through the 200 crimes and add each to the incidents feature group
for lat, lng, in zip(cdata.Y, data.X):
    incidents.add_child(
        folium.CircleMarker(
            [lat, lng],
            radius=7, # define how big you want the circle markers to be
            color='yellow',
            fill=True,
            fill_color='red',
            fill_opacity=0.4
        )
    )

san_map.add_child(incidents)


img

統計區域犯罪總數

from folium import plugins

# let's start again with a clean copy of the map of San Francisco
san_map = folium.Map(location=[37.77, -122.42], zoom_start=12,width='50%',height='50%')

# instantiate a mark cluster object for the incidents in the dataframe
incidents = plugins.MarkerCluster().add_to(san_map)

# loop through the dataframe and add each data point to the mark cluster
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
    folium.Marker(
        location=[lat, lng],
        icon=None,
        popup=label,
    ).add_to(incidents)

# add incidents to map
san_map.add_child(incidents)


img

以熱力圖的方式呈現

from folium.plugins import HeatMap

san_map = folium.Map(location=[37.77, -122.42], zoom_start=12,width='50%',height='50%')

# Convert data format
heatdata = data[['Y','X']].values.tolist()

# add incidents to map
HeatMap(heatdata).add_to(san_map)

san_map


img

在地圖上呈現GeoJSON邊界數據

import json
import requests

# url = 'https://cocl.us/sanfran_geojson'
url = 'san-francisco.geojson'
san_geo = f'{url}'
san_map = folium.Map(location=[37.77, -122.42], zoom_start=12,width='50%',height='50%')
folium.GeoJson(
    san_geo,
    style_function=lambda feature: {
        'fillColor': '#ffff00',
        'color': 'blue',
        'weight': 2,
        'dashArray': '5, 5'
    }
).add_to(san_map)

san_map


img

在GeoJSON上繪製Choropleth分級著色圖

# Count crime numbers in each neighborhood
disdata = pd.DataFrame(cdata['PdDistrict'].value_counts())
disdata.reset_index(inplace=True)
disdata.rename(columns={'index':'Neighborhood','PdDistrict':'Count'},inplace=True)

san_map = folium.Map(location=[37.77, -122.42], zoom_start=12,width='50%',height='50%')

folium.Choropleth(
    geo_data=san_geo,
    data=disdata,
    columns=['Neighborhood','Count'],
    key_on='feature.properties.DISTRICT',
    #fill_color='red',
    fill_color='YlOrRd',
    fill_opacity=0.7,
    line_opacity=0.2,
    highlight=True,
    legend_name='Crime Counts in San Francisco'
).add_to(san_map)

san_map


img3. 各地圖提供商瓦片服務地圖規則高德地圖

目前高德的瓦片地址有如下兩種:

前者是高德的新版地址,後者是老版地址。

高德新版的參數:

lang:可以通過zh_cn設置中文,en設置英文

size:基本無作用

scl:瓦片尺寸控制,1=256,2=512

style:設置影像和路網,style=6為衛星圖,style=7為街道圖,style=8為標註圖

ltype:線性控制,增加後,只對地圖要素進行控制,沒有文字註記,要素多少,是否透明

這些規律並不是絕對的,有可能有的組合某些參數不起作用。

谷歌地圖

目前谷歌的瓦片地址也存在兩種:

參數詳解:

百度地圖

百度當前的瓦片地址:

http://online{0-4}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&udt=202004151&scaler=2&p=0

http://api{0-3}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&udt=20180601&scale=1

http://its.map.baidu.com:8002/traffic/TrafficTileService?level={z}&x={x}&y={y}&time=1373790856265&label=web2D&;v=017

備註:瓦片地址中的x和y對應的並不是經緯度值,而是瓦片編號,中國主要地圖商的瓦片編號流派:

目前百度的瓦片編號比較特殊,Folium暫不支持。

其他參考資料:

https://github.com/geometalab/pyGeoTile

https://github.com/anzhihun/OpenLayers3Primer/blob/master/ch05/05-03.md

http://www.winseliu.com/blog/2018/01/30/map-started-guide/

https://github.com/CntChen/tile-lnglat-transform

騰訊地圖

騰訊地圖的瓦片地圖URL格式:

由於騰訊地圖使用的瓦片編碼時TMS,所以使用時需要額外的設置。具體如下:


其他底圖

{0,1,2,3}代表了url的subDomain,在請求時會隨機的在url中使用mt0、mt1、mt2、mt3。{z}代表zoom,即縮放級別,{x}代表列號,{y}代表行號。

GeoQ 官網有公開的多個基於 ArcGIS 的地圖服務,均可使用,詳見https://map.geoq.cn/arcgis/rest/services

4. 參考連結:

相關焦點

  • 使用Python和R繪製數據地圖的十七個經典案例
    在這篇博客中,我將一些優秀的用戶內核變成迷你教程,作為在Kaggle上發布的數據集進行繪製地圖的開始。這篇文章中,你將學習如何用Python和R,使用包括實際代碼示例的幾種方法來布局和可視化地理空間數據。
  • Python-Cartopy包(1):世界地圖的繪製
    由於該圖包的默認命令的參數都是外國人輸入的,在繪製國境線時,會有相當多的領土(比如藏南、阿克賽欽、臺灣)可能不被畫入我國,所以不推薦繪製國境線,必須繪製的情況下,也應規避這些地方或使用我國發布的有效地理信息。(
  • python繪圖 | 空間地圖上散點氣泡繪製
    今天的推文教程使用geopandas進行空間圖表的繪製(geopandas空間繪圖很方便,省去了很多的數據處理過程,而且也完美銜接matplotlib,學習python 空間繪圖的小夥伴可以看下啊),具體為空間氣泡圖的繪製,主要涉及的內容如下:geopandas geojson數據格式讀取並可視化展示geopandas
  • Python 可視化神器--Plotly
    Python第三方庫中我們最常用的可視化庫是 pandas,matplotlib,pyecharts,當然還有 Tableau,另外最近在學習過程中發現另一款可視化神器-Plotly,它是一款用來做數據分析和可視化的在線平臺,功能非常強大,可以在線繪製很多圖形比如條形圖、散點圖、餅圖、直方圖等等。
  • 如何用python來繪製四邊形-python繪製四邊形圖文教程來了
    python的應用有很多,其中還可以用python來繪製四邊形,下面羽憶教程網為您分享如何用python來繪製四邊形的詳細步驟。python繪製四邊形想要用python繪製四邊形,首先需要調用turtle模塊,這個turtle模塊是python內置的一個非常有趣的模塊,安裝python後自帶的,所以只需要簡單的導入就可以了。1、在python中先導入turtle模塊。
  • Python-plotnine 核密度空間插值可視化繪製
    好了,下面我們就開始今天的推文內容,本期推文主要包括:scipy.stats.gaussian_kde()函數進行核密度估計計算geopandas 繪製空間地圖及裁剪操作在上期推文中Python-geopandas 中國地圖繪製 中,我們使用了geopandas
  • 用Python畫一個中國地圖
    但在這些年默默的失敗背後,有一幫研究人員用 Python 幹出了一些驚天地泣鬼神的神器,使 Python 在數據研究領域做到了除了 R 語言以外基本無人能及的地步。 Jupyter 首先,第一神器是 Jupyter 。如果你是第一次使用,可能搞不清楚它的開發者做這麼個鬼東西出來幹什麼,說它是博客系統也不像,說它是web伺服器也不像,但它就是有用。
  • 工科神器matlab高校遭禁用,網友:關我p事,python可取而代之
    學過理工科的都知道,matlab可是做科研、做實驗的神器;通過matlab編程,不僅可以數學建模,還可以做人工智慧、深度學習;不僅可以用於數值計算,還可以用於繪製圖表,被一度認為是計算機學科、材料學科等必須掌握的技能。
  • 【解密】古人如何繪製地圖?
    艱苦測量:曾靠步量、記道車來測裡程測量是繪製任何地圖最首要的一步。據《春秋緯》記載,五帝之一的炎帝,為了度量大地而遠涉幾十萬裡。公元前兩千兩百多年,夏禹治水時「左準繩,右規矩,載四時,以開九州,通九道」。《山海經》也記載,夏禹派大章和豎亥兩位徒弟步量世界大小。這說明四千多年前,祖先就已經開展過規模較大的測繪工作。
  • Python-matplotlib: 散點圖的繪製
    .5,height=.5, color=region_color[c]) axins.add_patch(rect)axins.set_xticks([])axins.set_xlim(left=-5,right=35)axins.set_yticks([])axins.set_ylim(top=30,bottom=-5)axins.invert_yaxis()axins.axis('off')
  • 大三學生繪製北師大性騷擾地圖 堪稱校園裡的「防狼手冊」
    大三學生繪製北師大性騷擾地圖 堪稱校園裡的「防狼手冊」時間:2016-09-01 07:02   來源:川北在線整理   責任編輯:凌君 川北在線核心提示:原標題:大三學生繪製北師大性騷擾地圖 堪稱校園裡的防狼手冊 大三學生繪製北師大性騷擾地圖 提醒女生繞路很有必要 8月29日,一位來自北京師範大學中文系的大三學生康宸瑋用了四個月時間
  • Python繪製三維圖
    平常我們看到的物體一般是三維空間中的立體圖形,今天跟大家一起來學習用Python繪製立體圖形。
  • Python-Plotnine包: 類別插值地圖
    今天這篇推文,我們繼續空間數據可視化的最後一個系列-類別插值(categorical-spatial-interpolation) 可視化繪製的推文教程,這期我們使用Python進行繪製,涉及的知識點如下:sklearn.KNeighborsClassifier()機器學習應用
  • 如何用四步法快速繪製產業招商地圖?
    但話說回來,做產業招商地圖是個複雜事兒,一份拿來即用的招商地圖,少說也要兩三個月才能畫完,但招商工作迫在眉睫,一秒鐘都耽誤不得,這可怎麼辦呢? 今天,我們嘗試用四步法快速勾畫一張簡單的產業地圖。
  • 推薦: 一本「高顏值」的Python語言數據可視化圖書
    所以很有必要系統性地介紹python的繪圖語法系統,包括最基礎也最常用的matplotlib包、常用於統計分析的seaborn、最新出現類似R ggplot2語法的plotnine以及用於地理空間數據可視化的basemap包。在先介紹數據可視化基礎理論後,本書系統性地介紹了幾乎所有常見的二維和三維圖表的繪製方法,包括簡單的柱形圖系列、條形圖系列、折線圖系列,地圖系列等。
  • 【Python】用pyecharts繪製我國人口分布和遷移地圖
    由於我國省份較多,把數據放在地圖上展示會更加清晰,故本文用Python中的pyecharts庫進行人口分布和遷移繪圖展示。pyecharts的地圖數據主要來源於兩個模塊,一是Map,二是Geo。Map模塊主要實現「世界」、「國家」、「省」、「縣市」等行政地圖的顯示,而Geo主要實現熱力圖等功能地圖的顯示。本文致力於讓大家學會用Python在地圖上進行數據展示。
  • 古代沒有衛星測繪儀,如何繪製地圖?
    在沒有衛星的古代,古人要繪製地圖只能是人徒步測量,據說,炎帝為了測量地方,行走了幾十萬裡路,大禹治水前期也做非常多的工作,就有了後來的《禹跡圖》(宋代繪製)。
  • 【科研貓·繪圖】世界地圖繪製
    由於近期疫情的播散,而流行病學研究對疫情防控又至關重要,所以,最近湧現了一大批關於疾病流調的文章,這也使得很多研究人員在文章中需要繪製不同地區的地圖作為文章中的主圖
  • 古代是怎麼畫地圖的?沒有衛星沒有高科技,只靠兩招就能準確繪製
    比如中國最早的地理著作《山海經》,古人在書中記錄了大量難以考證的神話傳說,也記錄了許多山河的位置,這對當時人們研究地理信息非常有用。此外,目前出土最早的地圖是天水天茅灘秦墓出土的戰國地圖。共有七幅地圖,主要描繪戰國時期秦國的山川,但並不詳細。宋代造紙印刷業有了很大的發展,地圖的製作變得更加容易。當時宋宮收藏的國家地圖與現代地圖十分接近。
  • 手把手|如何用Python繪製JS地圖?
    用Python處理數據,然後用Folium將它在Leaflet地圖上進行可視化。 概念 Folium能夠將通過Python處理後的數據輕鬆地在交互式的Leaflet地圖上進行可視化展示。它不單單可以在地圖上展示數據的分布圖,還可以使用Vincent/Vega在地圖上加以標記。