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 相关文章推荐
python解析xml文件实例分享
Dec 04 Python
玩转python爬虫之cookie使用方法
Feb 17 Python
浅析python中的分片与截断序列
Aug 09 Python
详解常用查找数据结构及算法(Python实现)
Dec 09 Python
Python正则表达式常用函数总结
Jun 24 Python
Python3实现抓取javascript动态生成的html网页功能示例
Aug 22 Python
Python不使用int()函数把字符串转换为数字的方法
Jul 09 Python
使用python3实现操作串口详解
Jan 01 Python
python cv2在验证码识别中应用实例解析
Dec 25 Python
Python转换字典成为对象,可以用"."方式访问对象属性实例
May 11 Python
浅析Python迭代器的高级用法
Jul 16 Python
如何使用Python自动生成报表并以邮件发送
Oct 15 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 实现多服务器共享 SESSION 数据
2009/08/15 PHP
将一维或多维的数组连接成一个字符串的php代码
2010/08/08 PHP
php设计模式 Builder(建造者模式)
2011/06/26 PHP
全面解析PHP操作Memcache基本函数
2016/07/14 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
2017/06/21 PHP
php实现的生成排列算法示例
2019/07/25 PHP
写出更好的JavaScript程序之undefined篇(中)
2009/11/23 Javascript
JS上传图片前的限制包括(jpg jpg gif及大小高宽)等
2012/12/19 Javascript
高效的获取当前元素是父元素的第几个子元素
2013/10/15 Javascript
Javascript获取数组中的最大值和最小值的方法汇总
2016/01/01 Javascript
jquery插件uploadify多图上传功能实现代码
2016/08/12 Javascript
BootStrap按钮标签及基本样式
2016/11/23 Javascript
js推箱子小游戏步骤代码解析
2018/01/10 Javascript
vuejs选中当前样式active的实例
2018/08/22 Javascript
微信小程序实现卡片左右滑动效果的示例代码
2019/05/01 Javascript
javascript实现鼠标点击生成文字特效
2019/12/24 Javascript
浅谈Vue.use到底是什么鬼
2020/01/21 Javascript
javascript设计模式 ? 装饰模式原理与应用实例分析
2020/04/14 Javascript
vue 子组件watch监听不到prop的解决
2020/08/09 Javascript
利用python获得时间的实例说明
2013/03/25 Python
java直接调用python脚本的例子
2014/02/16 Python
python使用xauth方式登录饭否网然后发消息
2014/04/11 Python
复化梯形求积分实例——用Python进行数值计算
2019/11/20 Python
解决tensorboard多个events文件显示紊乱的问题
2020/02/15 Python
css3遮罩层镂空效果的多种实现方法
2020/05/11 HTML / CSS
HTML5本地存储和本地数据库实例详解
2017/09/05 HTML / CSS
美国在线印刷公司:PsPrint
2017/10/12 全球购物
澳大利亚制造的羊皮靴:Original UGG Boots
2017/11/13 全球购物
速比涛英国官网:Speedo英国
2019/07/15 全球购物
乌克兰巴士票购买网站:inBus
2021/03/12 全球购物
2014年小学国庆节活动方案
2014/09/16 职场文书
荒岛余生观后感
2015/06/09 职场文书
中学教师教学工作总结
2015/08/13 职场文书
导游词之新疆尼雅遗址
2019/10/16 职场文书
python中数组和列表的简单实例
2022/03/25 Python
Valheim服务器 Mod修改安装教程 【ValheimPlus】
2022/12/24 Servers