Python绘制地图神器folium的新人入门指南


Posted in Python onMay 23, 2021

一、简介

想通过 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

Python绘制地图神器folium的新人入门指南

3.1.2 国家地图

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

Python绘制地图神器folium的新人入门指南

3.1.3 市级地图

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

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

Python绘制地图神器folium的新人入门指南

显示效果确实是不如百度的?。

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

Python绘制地图神器folium的新人入门指南

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

Python绘制地图神器folium的新人入门指南

添加圆形标记用 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

Python绘制地图神器folium的新人入门指南

3.3.2 点击获取经纬度

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

m.add_child(folium.LatLngPopup())

m

通过点击鼠标便可以获取点击出的经纬度。

Python绘制地图神器folium的新人入门指南

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

Python绘制地图神器folium的新人入门指南

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

Python绘制地图神器folium的新人入门指南

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)

Python绘制地图神器folium的新人入门指南

3.6 自定义地图区域

folium 一个非常有优势的功能就是自定义区域的绘制了,只要有区域的边界数据,就可以在地图中以多种多样的形式展现出来,这里以 folium 官方的美国地图为例,源数据是一个 .json 文件,里面包含了各个地区(美国各州)的特征(包括边界经纬度列表、简称等),源数据传送门,其数据格式如下:

Python绘制地图神器folium的新人入门指南

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

Python绘制地图神器folium的新人入门指南

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

Python绘制地图神器folium的新人入门指南

我们再把收入等数据连接到上表中

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

Python绘制地图神器folium的新人入门指南

最终绘制出的来的地图如下:

Python绘制地图神器folium的新人入门指南

除此之外,还有很多非常有趣的功能,这里就不一一列举了,感兴趣的可以参考官方的文档。

四、竞品对比与优劣势

国内的竞品为百度的 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内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python socket 超时设置 errno 10054
Jul 01 Python
python实现的多线程端口扫描功能示例
Jan 21 Python
python实现mysql的读写分离及负载均衡
Feb 04 Python
使用实现pandas读取csv文件指定的前几行
Apr 20 Python
Python实现的直接插入排序算法示例
Apr 29 Python
Django实现全文检索的方法(支持中文)
May 14 Python
Python 给屏幕打印信息加上颜色的实现方法
Apr 24 Python
Python进程,多进程,获取进程id,给子进程传递参数操作示例
Oct 11 Python
基于Python+Appium实现京东双十一自动领金币功能
Oct 31 Python
python 多维高斯分布数据生成方式
Dec 09 Python
python内打印变量之%和f的实例
Feb 19 Python
Django设置Postgresql的操作
May 14 Python
Python关于OS文件目录处理的实例分享
May 23 #Python
python引入其他文件夹下的py文件具体方法
Python 解决空列表.append() 输出为None的问题
May 23 #Python
Python - 10行代码集2000张美女图
python办公自动化之excel的操作
May 23 #Python
python爬取豆瓣电影TOP250数据
May 23 #Python
基于Python绘制子图及子图刻度的变换等的问题
You might like
php使用curl简单抓取远程url的方法
2015/03/13 PHP
PHP版本升级到7.x后wordpress的一些修改及wordpress技巧
2015/12/25 PHP
Laravel学习笔记之Artisan命令生成自定义模板的方法
2018/11/22 PHP
PHP解决高并发的优化方案实例
2020/12/10 PHP
Avengerls vs KG BO3 第一场2.18
2021/03/10 DOTA
JavaScript 使用技巧精萃(.net html
2009/04/25 Javascript
javascript parseInt与Number函数的区别
2010/01/21 Javascript
jQuery源码解读之hasClass()方法分析
2015/02/20 Javascript
深入理解JavaScript系列(42):设计模式之原型模式详解
2015/03/04 Javascript
JS修改地址栏参数实例代码
2016/06/14 Javascript
JSON与String互转的实现方法(Javascript)
2016/09/27 Javascript
js HTML5上传示例代码完整版
2016/10/10 Javascript
jQuery中animate的几种用法与注意事项
2016/12/12 Javascript
canvas简单快速的实现知乎登录页背景效果
2017/05/08 Javascript
Vue父子组建的简单通信之控制开关Switch的实现
2018/06/04 Javascript
如何解决.vue文件url引用文件的问题
2019/01/18 Javascript
微信小程序 image组件遇到的问题
2019/05/28 Javascript
Layui实现带查询条件的分页
2019/07/27 Javascript
详解Vue的mixin策略
2020/11/19 Vue.js
[02:45]DOTA2英雄基础教程 伐木机
2013/12/23 DOTA
[10:34]DOTA2上海特级锦标赛全纪录
2016/03/25 DOTA
python检查序列seq是否含有aset中项的方法
2015/06/30 Python
Python实现二维曲线拟合的方法
2018/12/29 Python
Django项目使用ckeditor详解(不使用admin)
2019/12/17 Python
TensorFlow实现模型断点训练,checkpoint模型载入方式
2020/05/26 Python
基于python requests selenium爬取excel vba过程解析
2020/08/12 Python
html5使用canvas画空心圆与实心圆
2014/12/15 HTML / CSS
Boutique 1美国:阿联酋奢侈时尚零售商
2017/10/16 全球购物
NYX Professional Makeup官方网站:专业彩妆和美容产品
2019/10/29 全球购物
几道数据库的面试题或笔试题
2014/05/31 面试题
财务与信息服务专业推荐信
2013/11/28 职场文书
大专毕业自我鉴定
2014/02/04 职场文书
实习报告评语
2014/04/26 职场文书
留学推荐信(中英文版)
2015/03/26 职场文书
检讨书怎么写?
2019/06/21 职场文书
css让页脚保持在底部位置的四种方案
2022/07/23 HTML / CSS