今天給大家介紹一個非常 NB 的Python 庫,專門用來繪制地圖的,它叫 Folium 。
1. Folium簡介
Folium是一個基于leaflet.js的Python地圖庫,其中,Leaflet是一個非常輕的前端地圖可視化庫。即可以使用Python語言調(diào)用Leaflet的地圖可視化能力。它不單單可以在地圖上展示數(shù)據(jù)的分布圖,還可以使用Vincent/Vega在地圖上加以標記。Folium可以讓你用Python強大生態(tài)系統(tǒng)來處理數(shù)據(jù),然后用Leaflet地圖來展示。
Folium中有許多來自O(shè)penStreetMap、MapQuest Open、MapQuestOpen Aerial、Mapbox和Stamen的內(nèi)建地圖元件,而且支持使用Mapbox或Cloudmade的API密鑰來定制個性化的地圖元件。Folium支持GeoJSON和TopoJSON兩種文件格式的疊加,也可以將數(shù)據(jù)連接到這兩種文件格式的疊加層,最后可使用color-brewer配色方案創(chuàng)建分布圖。
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)
參數(shù)說明:
location (tuple or list, default None):緯度和經(jīng)度
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的經(jīng)度、緯度表示坐標。
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地圖類的其他參數(shù): https://leafletjs.com/reference-1.5.1.html#map
“tiles”參數(shù)可選值:
“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”的自定義設(shè)置:
img
地球上同一個地理位置的經(jīng)緯度,在不同的坐標系中,會有少量偏移,國內(nèi)目前常見的坐標系主要分為三種:
地球坐標系——WGS84:常見于GPS設(shè)備,Google地圖等國際標準的坐標體系。
火星坐標系——GCJ-02:中國國內(nèi)使用的被強制加密后的坐標體系,高德坐標就屬于該種坐標體系。
百度坐標系——BD-09:百度地圖所使用的坐標體系,是在火星坐標系的基礎(chǔ)上又進行了一次加密處理。
所以在設(shè)置“tiles”時需要考慮目前手中得經(jīng)緯度屬于那種坐標系。
由于投影坐標系中沒有GCJ-02和BD-09對應(yīng)的標識,所以在自定義瓦片時主要經(jīng)緯度能匹配上,crs中的設(shè)置可保持不變。更多詳情介紹請看:瓦片坐標系學(xué)習(xí)
如果需要將地圖保存,只需執(zhí)行: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_cnsize=1scale=1style=8x={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類可以設(shè)置color, icon_color, icon, angle, prefix這5個參數(shù):
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網(wǎng)站中找到對應(yīng)的名字,并設(shè)置prefix參數(shù)為'fa'
angle以度為單位設(shè)置
其他:
m.add_child(folium.LatLngPopup()) #顯示鼠標點擊點經(jīng)緯度 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)
添加多邊形
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)
Folium的其他高級應(yīng)用
在地圖上顯示前200條犯罪數(shù)據(jù)
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') #犯罪數(shù)據(jù),包含犯罪所在經(jīng)緯度 # 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)
統(tǒng)計區(qū)域犯罪總數(shù)
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)
以熱力圖的方式呈現(xiàn)
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
在地圖上呈現(xiàn)GeoJSON邊界數(shù)據(jù)
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
在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
3. 各地圖提供商瓦片服務(wù)地圖規(guī)則 高德地圖
目前高德的瓦片地址有如下兩種:
http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}y={y}z={z}lang=zh_cnsize=1scl=1style=7ltype=1
http://webst0{1-4}.is.autonavi.com/appmaptile?style=7x={x}y={y}z={z}
前者是高德的新版地址,后者是老版地址。
高德新版的參數(shù):
lang:可以通過zh_cn設(shè)置中文,en設(shè)置英文
size:基本無作用
scl:瓦片尺寸控制,1=256,2=512
style:設(shè)置影像和路網(wǎng),style=6為衛(wèi)星圖,style=7為街道圖,style=8為標注圖
ltype:線性控制,增加后,只對地圖要素進行控制,沒有文字注記,要素多少,是否透明
這些規(guī)律并不是絕對的,有可能有的組合某些參數(shù)不起作用。
谷歌地圖
目前谷歌的瓦片地址也存在兩種:
http://mt{0-3}.google.cn/vt/lyrs=mhl=zh-CNgl=cnx={x}y={y}z={z}
http://mt{0-3}.google.com/vt/lyrs=mhl=zh-CNgl=cnx={x}y={y}z={z}
參數(shù)詳解:
lyrs = 類型
h = roads only 僅限道路
m = standard roadmap 標準路線圖
p = terrain 帶標簽的地形圖
r = somehow altered roadmap 某種改變的路線圖
s = satellite only 僅限衛(wèi)星
t = terrain only 僅限地形
y = hybrid 帶標簽的衛(wèi)星圖
gl = 坐標系
CN = 中國火星坐標系
hl = 地圖文字語言
zh-CN = 中文
en-US = 英文
x = 瓦片橫坐標
y = 瓦片縱坐標
z = 縮放級別 衛(wèi)星圖0-14,路線圖0-17
百度地圖
百度當前的瓦片地址:
http://online{0-4}.map.bdimg.com/onlinelabel/?qt=tilex={x}y={y}z={z}styles=pludt=202004151scaler=2p=0
http://api{0-3}.map.bdimg.com/customimage/tile?x={x}y={y}z={z}udt=20180601scale=1
http://its.map.baidu.com:8002/traffic/TrafficTileService?level={z}x={x}y={y}time=1373790856265label=web2D;v=017
備注:瓦片地址中的x和y對應(yīng)的并不是經(jīng)緯度值,而是瓦片編號,中國主要地圖商的瓦片編號流派:
目前百度的瓦片編號比較特殊,F(xiàn)olium暫不支持。
其他參考資料:
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格式:
http://rt1.map.gtimg.com/realtimerender?z={z}x={x}y={y}type=vectorstyle=0
由于騰訊地圖使用的瓦片編碼時TMS,所以使用時需要額外的設(shè)置。具體如下:
其他底圖
{0,1,2,3}代表了url的subDomain,在請求時會隨機的在url中使用mt0、mt1、mt2、mt3。{z}代表zoom,即縮放級別,{x}代表列號,{y}代表行號。
GeoQ 官網(wǎng)有公開的多個基于 ArcGIS 的地圖服務(wù),均可使用,詳見
https://map.geoq.cn/arcgis/rest/services
到此這篇關(guān)于Python 里最強的地圖繪制神器的文章就介紹到這了,更多相關(guān)Python地圖繪制神器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章: Python基礎(chǔ)之畫圖神器matplotlib Python繪制K線圖之可視化神器pyecharts的使用 Python繪制詞云圖之可視化神器pyecharts的方法 python 視頻下載神器(you-get)的具體使用 微軟開源最強Python自動化神器Playwright(不用寫一行代碼) python實現(xiàn)跨年表白神器--你值得擁有 Python 可視化神器Plotly詳解 地圖可視化神器kepler.gl python接口的使用方法 10款最佳Python開發(fā)工具推薦,每一款都是神器 推薦技術(shù)人員一款Python開源庫(造數(shù)據(jù)神器) 詳解Python可視化神器Yellowbrick使用 Python實戰(zhàn)之能監(jiān)控文件變化的神器—看門狗