当前位置:主页 > 查看内容

Python绘制地图神器,上手直接开大!

发布时间:2021-05-22 00:00| 位朋友查看

简介:大家晚上好,我是小五 之前给大家介绍过多种Python可视化模块,但使用他们进行地理可视化都很简陋。 所以想要绘制更精美的可视化地图?想在地图上自由的设置各种参数?想获得灵活的交互体验? 今天它就来了,Python绘制地图神器folium,上手直接开大! 一、foliu……

大家晚上好,我是小五

之前给大家介绍过多种Python可视化模块,但使用他们进行地理可视化都很简陋。

所以想要绘制更精美的可视化地图?想在地图上自由的设置各种参数?想获得灵活的交互体验?

今天它就来了,Python绘制地图神器folium,上手直接开大!

一、folium简介和安装

folium 建立在 Python 生态系统的数据应用能力和 Leaflet.js 库的映射能力之上,在Python中操作数据,然后通过 folium 在 Leaflet 地图中可视化。

folium 相比较于国内百度的 pyecharts 灵活性更强,能够自定义绘制区域,并且展现形式更加多样化。[1]

1. folium的简介

  • Folium是建立在 Python 生态系统的数据整理 Datawrangling 能力和 Leaflet.js 库的映射能力之上的开源库。用 Python 处理数据,然后用 Folium 将它在 Leaflet 地图上进行可视化。Folium能够将通过 Python 处理后的数据轻松地在交互式的 Leaflet 地图上进行可视化展示。它不单单可以在地图上展示数据的分布图,还可以使用 Vincent/Vega 在地图上加以标记。
  • 这个开源库中有许多来自 OpenStreetMap、MapQuest Open、MapQuestOpen Aerial、Mapbox和Stamen 的内建地图元件,而且支持使用 Mapbox 或 Cloudmade 的 API 密钥来定制个性化的地图元件。Folium支持 GeoJSON 和 TopoJSON 两种文件格式的叠加,也可以将数据连接到这两种文件格式的叠加层,最后可使用 color-brewer 配色方案创建分布图。
  • Folium可以让你用 Python 强大生态系统来处理数据,然后用 Leaflet 地图来展示。Folium内置一些来自 OpenStreetMap、MapQuest Open、MapQuest Open Aerial、Mapbox和Stamen 的地图元件(tilesets),并且支持用 Mapbox 或者 Cloudmade API keys 来自定义地图元件。Folium支持 GeoJSON 和 TopJSON 叠加(overlays),绑定数据来创造一个分级统计图(Choropleth map)。但是,Folium库绘制热点图的时候,需要联网才可显示

2. 安装folium

  1. pip install folium -i http://pypi.douban.com/simple --trusted-host pypi.douban.com 

👆这里直接使用了国内豆瓣源

二、基本使用

folium显示地图的类为 folium.Map,类的声明如下:

  1. class 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,值越大比例尺越小,地图放大级别越大
  • control_scale:Bool型,控制是否在地图上添加比例尺,默认为 False 即不添加
  • tiles:显示样式,默认 "OpenStreetMap",也就是开启街道显示
  • crs:地理坐标参考系统,默认为 "EPSG3857"

1. 各级别地图

世界地图

  1. import folium 
  2.  
  3. print(folium.__version__) 
  4.  
  5. # define the world map 
  6. world_map = folium.Map() 
  7. # save world map 
  8. world_map.save('test_01.html'

结果如下:

  1. 当前folium版本:0.11.0 

国家地图

  1. import folium 
  2. # define the national map 
  3. national_map = folium.Map(location=[35.3, 100.6], zoom_start=4) 
  4. # save national map 
  5. national_map.save('test_02.html'

结果如下:

市级地图

其实改变地图显示也就是改变显示的经纬度和缩放比例,省级、市级、县级用法相似,这里举一个市级的例子为例,如北京市:

  1. import folium 
  2. # define the national map 
  3. city_map = folium.Map(location=[39.93, 116.40], zoom_start=10) 
  4. # save national map 
  5. city_map.save('test_03.html'

2. 在地图上标记

普通标记

添加普通标记用 Marker,可以选择标记的图案。

  1. import folium 
  2.  
  3. bj_map = folium.Map(location=[39.93, 115.40], zoom_start=12, tiles='Stamen Terrain'
  4.  
  5. folium.Marker( 
  6.     location=[39.95, 115.33], 
  7.     popup='Mt. Hood Meadows'
  8.     icon=folium.Icon(icon='cloud'
  9. ).add_to(bj_map) 
  10.  
  11. folium.Marker( 
  12.     location=[39.96, 115.32], 
  13.     popup='Timberline Lodge'
  14.     icon=folium.Icon(color='green'
  15. ).add_to(bj_map) 
  16.  
  17. folium.Marker( 
  18.     location=[39.93, 115.34], 
  19.     popup='Some Other Location'
  20.     icon=folium.Icon(color='red', icon='info-sign')    # 标记颜色  图标 
  21. ).add_to(bj_map) 
  22.  
  23. bj_map.save('test_04.html'

结果如下:

圆形标记

添加圆形标记用 Circle 以及 CircleMarker

  1. import folium 
  2.  
  3. bj_map = folium.Map(location=[39.93, 116.40], zoom_start=12, tiles='Stamen Toner'
  4.  
  5. folium.Circle( 
  6.     radius=200, 
  7.     location=(39.92, 116.43), 
  8.     popup='The Waterfront'
  9.     color='#00FFFF',   # 颜色 
  10.     fill=False,        # 填充 
  11. ).add_to(bj_map) 
  12.  
  13. folium.CircleMarker( 
  14.     location=(39.93, 116.38), 
  15.     radius=50,   # 圆的半径 
  16.     popup='Laurelhurst Park'
  17.     color='#FF1493'
  18.     fill=True
  19.     fill_color='#FFD700' 
  20. ).add_to(bj_map) 
  21.  
  22. bj_map.save('test_05.html'

结果如下:

动态放置标记

  1. import folium 
  2.  
  3. dynamic_tagging = folium.Map( 
  4.     location=[46.8527, -121.7649], 
  5.     tiles='Stamen Terrain'
  6.     zoom_start=13 
  7.  
  8. folium.Marker( 
  9.     [46.8354, -121.7325], 
  10.     popup='Camp Muir' 
  11. ).add_to(dynamic_tagging) 
  12.  
  13. dynamic_tagging.add_child(folium.ClickForMarker(popup='Waypoint')) 
  14. dynamic_tagging.save('test_06.html'

结果如下:

更多详细使用可以参考官方文档:http://python-visualization.github.io/folium/quickstart.html[2]

三、实战案例

以将停车场地理位置数据可视化在地图上示例,熟悉 folium 地图可视化的使用。

1. 获取经纬度数据

停车场地理位置数据来源于网络,数据真实可靠,下面先利用 Python 爬虫获取数据

  1. #数据来源:http://219.136.133.163:8000/Pages/Commonpage/login.aspx 
  2.  
  3. import requests 
  4. import csv 
  5. import json 
  6. import logging 
  7.  
  8. headers = { 
  9.     'X-Requested-With''XMLHttpRequest'
  10.     'User-Agent''Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36' 
  11. logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s'
  12. url = 'http://219.136.133.163:8000/Pages/Commonpage/AsyGetData.asmx/GetParkList' 
  13. s = requests.session() 
  14. s.get(url, headers=headers) 
  15. for i in range(1, 318): 
  16.     data = { 
  17.         'cp': str(i), 
  18.         'ps''10'
  19.         'kw'''
  20.         'lon''undefined'
  21.         'lat''undefined'
  22.         'type''undefined' 
  23.     } 
  24.     url = 'http://219.136.133.163:8000/Pages/Commonpage/AsyGetData.asmx/GetParkList' 
  25.     # post提交表单数据 
  26.     res = s.post(url, data=data, headers=headers) 
  27.     # 重新设置编码 
  28.     res.encoding = 'utf-8' 
  29.     # str转json  便于提取数据 
  30.     result = json.loads(res.text)['Result'
  31.     for j in result: 
  32.         park_name = j['ParkName'
  33.         Lon = j['Longitude'
  34.         Lat = j['Latitude'
  35.         with open('parkings.csv''a+', newline='', encoding='gb18030'as f: 
  36.             f_csv = csv.writer(f) 
  37.             f_csv.writerow([park_name, Lon, Lat]) 
  38.             logging.info([park_name, Lon, Lat]) 

结果如下:

共有 3170 个停车场地理位置数据

2. folium地图可视化

  1. import pandas as pd 
  2. import folium 
  3.  
  4. # 读取csv数据 
  5. data = pd.read_csv('parkings.csv', encoding='gbk'
  6. # 传入纬度和经度数据 
  7. park_map = folium.Map(location=[data['latitude'].mean(), data['longitude'].mean()], zoom_start=10, control_scale=True,) 
  8. # 实例化 folium.map.FeatureGroup 对象 
  9. incidents = folium.map.FeatureGroup() 
  10. for name,row in data.iterrows(): 
  11.     incidents.add_child( 
  12.         folium.CircleMarker(            # CircleMarker表示花圆 
  13.             (row["latitude"], row["longitude"]),   # 每个停车场的经纬度坐标 
  14.             radius=7,                   # 圆圈半径 
  15.             color='#FF1493',            # 标志的外圈颜色 
  16.             fill=True,                  # 是否填充 
  17.             fill_color='#00FF00',       # 填充颜色 
  18.             fill_opacity=0.4            # 填充透明度 
  19.         ) 
  20.     ) 
  21.  
  22. park_map.add_child(incidents) 
  23. park_map.save('park_map1.html'

效果如下:

这样看起来有点乱,下面我们来统计一下各个局域的停车场数量

  1. import pandas as pd 
  2. import folium 
  3. from folium import plugins 
  4.  
  5. data = pd.read_csv('parkings.csv', encoding='gbk'
  6. park_map = folium.Map(location=[data['latitude'].mean(), data['longitude'].mean()], zoom_start=10, control_scale=True,) 
  7. marker_cluster = plugins.MarkerCluster().add_to(park_map) 
  8.  
  9. for name,row in data.iterrows(): 
  10.     folium.Marker(location=[row["latitude"], row["longitude"]]).add_to(marker_cluster) 
  11. park_map.save('park_map2.html'

效果如下:

这样能对各个局域停车场的数量在地图上进行统计,将图不断放大以后,还可以显示每个停车场的具体位置,非常方便。


本文转载自网络,原文链接:https://mp.weixin.qq.com/s?__biz=MzU5Nzg5ODQ3NQ==&mid=2247507651&idx=2&sn=6ef91748fdd0c7706be8bb6d59f23f4c&chksm=fe4efb47c9397251822787c59fa8bc6fb82d2952c03e38fa05af703497e7ee2f6f3dcb12618b&mpshare=1&
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐