Python如何使用bokeh包和geojson数据绘制地图


Posted in Python onMarch 21, 2020

最近要绘制伦敦区地图,查阅了很多资料后最终选择使用bokeh包以及伦敦区的geojson数据绘制。
bokeh是基于python的绘图工具,可以绘制各种类型的图表,支持geojson数据的读取及绘制地图。

安装bokeh

$ pip install bokeh

软件版本

python-3.7.7bokeh-2.0.0

数据来源

伦敦地图数据来源于Highmaps地图数据集。下载的是英国的地图数据united-kindom.geo.json。需要对得到的数据进行预处理才能得到只含伦敦地区的数据。这需要对geojson数据的格式有一定的了解。在对数据进行处理之前,先看如何绘制英国地图。

绘制英国地图

from bokeh.plotting import curdoc, figure
from bokeh.models import GeoJSONDataSource

# 读入英国地图数据并传给GeoJSONDataSource
with open("united-kindom.geo.json", encoding="utf8") as f:
  geo_source = GeoJSONDataSource(geojson=f.read())
# 设置一张画布
p = figure(width=500, height=500)
# 使用patches函数以及geo_source绘制地图
p.patches(xs='xs', ys='ys', source=geo_source)

curdoc().add_root(p)

上述代码可以绘制出英国地图。将上述代码保存为test.py,在终端运行

$ bokeh serve --show test.py

这会自动打开浏览器,并显示英国地图。
运行结果如图:

Python如何使用bokeh包和geojson数据绘制地图

获取伦敦地区数据

获取伦敦地区数据可以手动从united-kingdom.geo.json文件中筛选出伦敦的数据,也可以先用python先把数据过滤一遍,然后将数据传给bokeh。这需要对geojson文件格式有一定的了解,在此不详细介绍。

from bokeh.plotting import curdoc, figure
from bokeh.models import GeoJSONDataSource
import json

# 用json库读取数据
with open("united-kindom.geo.json", encoding="utf8") as f:
  data = json.loads(f.read())
# 判断是不是伦敦地区数据
def isInLondon(district):
  if 'type' in district['properties'] and 'london borough' in district['properties']['type'].lower():
    return True
  if 'type-en' in district['properties'] and 'london borough' in district['properties']['type'].lower():
    return True
  if 'woe-name' in district['properties'] and 'city of london' in district['properties']['woe-name'].lower():
    return True
  return False
# 过滤数据
data['features'] = list(filter(isInLondon, data['features']))
#
geo_source = GeoJSONDataSource(geojson=json.dumps(data))
p = figure(width=500, height=500)
p.patches(xs='xs', ys='ys', source=geo_source)

curdoc().add_root(p)

运行结果如图:

Python如何使用bokeh包和geojson数据绘制地图

美化

上面的伦敦地图只是一个大概的轮廓,下面对地图添加一系列功能。

添加各区轮廓线

p.patches(xs='xs', ys='ys', fill_alpha=0.7, # 画轮廓线
    line_color='white', # 线的颜色
    line_width=0.5,   # 线的宽度
    source=geo_source)

现在地图区域轮廓很清晰。

添加颜色

# 为每一个地区增加一个color属性
for i in range(len(data['features'])):
  data['features'][i]['properties']['color'] = ['blue', 'red', 'yellow', 'orange', 'gray', 'purple'][i % 6]
p.patches(xs='xs', ys='ys', fill_alpha=0.7,
    line_color='white',
    line_width=0.5,
    color="color",  # 增加颜色属性,这里的"color"对应每个地区的color属性
    source=geo_source)

现在地图五颜六色。

增加图注

import random
# 随机产生数据用于展示
for i in range(len(data['features'])):
  data['features'][i]['properties']['number'] = random.randint(0, 20_000)
p = figure(width=500, height=500,
    tooltips="@name, number: @number" # 使用tooltips生成图注,@+属性名称,这里的name是数据中原本有的,number是新近添加的。
  )

现在鼠标放到区域上时,会显示"区域名, number: 数字"。

去掉坐标轴与背景线

p.axis.axis_label = None
p.axis.visible = False
p.grid.grid_line_color = None

最终代码

from bokeh.plotting import curdoc, figure
from bokeh.models import GeoJSONDataSource
import json
import random
with open("united-kindom.geo.json", encoding="utf8") as f:
  data = json.loads(f.read())

def isInLondon(district):
  if 'type' in district['properties'] and 'london borough' in district['properties']['type'].lower():
    return True
  if 'type-en' in district['properties'] and 'london borough' in district['properties']['type'].lower():
    return True
  if 'woe-name' in district['properties'] and 'city of london' in district['properties']['woe-name'].lower():
    return True
  return False

data['features'] = list(filter(isInLondon, data['features']))
for i in range(len(data['features'])):
  data['features'][i]['properties']['color'] = ['blue', 'red', 'yellow', 'orange', 'gray', 'purple'][i % 6]
  data['features'][i]['properties']['number'] = random.randint(0, 20_000)

geo_source = GeoJSONDataSource(geojson=json.dumps(data))
p = figure(width=500, height=500,
    tooltips="@name, number: @number")
p.patches(xs='xs', ys='ys', fill_alpha=0.7,
    line_color='white',
    line_width=0.5,
    color="color",
    source=geo_source)

p.axis.axis_label = None
p.axis.visible = False
p.grid.grid_line_color = None

curdoc().add_root(p)

伦敦地图完成了

Python如何使用bokeh包和geojson数据绘制地图

总结

最开始想用pyecharts做的,但是pyecharts并没有伦敦的地图。折腾半天,最后只好自己找geojson数据来画地图。

找到了很多关于地图的数据和工具,比如上文中提到的highmap数据集,以及DataV.altas,这个工具可以可视化地提取中国区域的地图数据,但感觉比起自己找数据,画中国地图还是pyecharts来得实在。

数据最重要。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
web.py获取上传文件名的正确方法
Aug 26 Python
python关键字and和or用法实例
May 28 Python
python 实现删除文件或文件夹实例详解
Dec 04 Python
Python爬虫包 BeautifulSoup  递归抓取实例详解
Jan 28 Python
python制作小说爬虫实录
Aug 14 Python
Python使用matplotlib的pie函数绘制饼状图功能示例
Jan 08 Python
PyCharm代码格式调整方法
May 23 Python
解决.ui文件生成的.py文件运行不出现界面的方法
Jun 19 Python
pyqt5 删除layout中的所有widget方法
Jun 25 Python
pytorch 自定义参数不更新方式
Jan 06 Python
Python matplotlib修改默认字体的操作
Mar 05 Python
Django后端分离 使用element-ui文件上传方式
Jul 12 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
Mar 20 #Python
python+opencv实现移动侦测(帧差法)
Mar 20 #Python
Java Spring项目国际化(i18n)详细方法与实例
Mar 20 #Python
Python 自由定制表格的实现示例
Mar 20 #Python
python实现opencv+scoket网络实时图传
Mar 20 #Python
python实现同一局域网下传输图片
Mar 20 #Python
python实现udp传输图片功能
Mar 20 #Python
You might like
PHP SPL标准库之数据结构栈(SplStack)介绍
2015/05/12 PHP
php无序树实现方法
2015/07/28 PHP
php获取字符串前几位的实例(substr返回字符串的子串用法)
2017/03/08 PHP
php使用lua+redis实现限流,计数器模式,令牌桶模式
2019/04/04 PHP
PHP实现文件上传操作和封装
2020/03/04 PHP
前端开发部分总结[兼容性、DOM操作、跨域等](持续更新)
2010/03/04 Javascript
JavaScript将相对地址转换为绝对地址示例代码
2013/07/19 Javascript
在JavaScript中实现类的方式探讨
2013/08/28 Javascript
jQuery中:password选择器用法实例
2015/01/03 Javascript
jQuery ajax提交Form表单实例(附demo源码)
2016/04/06 Javascript
axios+Vue实现上传文件显示进度功能
2019/04/14 Javascript
浅析 Vue 3.0 的组装式 API(一)
2020/08/31 Javascript
编写v-for循环的技巧汇总
2020/12/01 Javascript
Vue过滤器,生命周期函数和vue-resource简单介绍
2021/01/12 Vue.js
Python随机生成手机号、数字的方法详解
2017/07/21 Python
Python批量提取PDF文件中文本的脚本
2018/03/14 Python
PyTorch线性回归和逻辑回归实战示例
2018/05/22 Python
python2 与 python3 实现共存的方法
2018/07/12 Python
总结python中pass的作用
2019/02/27 Python
django 单表操作实例详解
2019/07/30 Python
Python3常见函数range()用法详解
2019/12/30 Python
Python面向对象原理与基础语法详解
2020/01/02 Python
如何使用pandas读取txt文件中指定的列(有无标题)
2020/03/05 Python
浅谈JupyterNotebook导出pdf解决中文的问题
2020/04/22 Python
Django正则URL匹配实现流程解析
2020/11/13 Python
如何用python写个模板引擎
2021/01/14 Python
美国婴儿用品及配件购买网站:Munchkin
2019/04/03 全球购物
财务会计专业应届毕业生求职信
2013/10/18 职场文书
食品营养与检测应届生求职信
2013/11/08 职场文书
市场营销战略计划书
2014/05/06 职场文书
班级文化标语
2014/06/23 职场文书
红领巾广播站广播稿
2014/10/19 职场文书
农村婚庆主持词
2015/06/29 职场文书
领导激励员工的演讲稿,各种会上用得到,建议收藏
2019/08/13 职场文书
详解Python中__new__方法的作用
2022/03/31 Python
git stash(储藏)的用法总结
2022/06/25 Servers