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中使用urllib2伪造HTTP报头的2个方法
Jul 07 Python
python访问mysql数据库的实现方法(2则示例)
Jan 06 Python
Python使用pip安装pySerial串口通讯模块
Apr 20 Python
pandas Dataframe行列读取的实例
Jun 08 Python
python 对dataframe下面的值进行大规模赋值方法
Jun 09 Python
python实现在遍历列表时,直接对dict元素增加字段的方法
Jan 15 Python
Python可变和不可变、类的私有属性实例分析
May 31 Python
关于python中密码加盐的学习体会小结
Jul 15 Python
python实现126邮箱发送邮件
May 20 Python
Python如何在循环内使用list.remove()
Jun 01 Python
pytorch判断是否cuda 判断变量类型方式
Jun 23 Python
Python把图片转化为pdf代码实例
Jul 28 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错误日志 display_errors与log_errors的区别
2012/10/09 PHP
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
浅谈php的优缺点
2015/07/14 PHP
thinkPHP中volist标签用法示例
2016/12/06 PHP
PHP无限极分类函数的实现方法详解
2017/04/15 PHP
[原创]保存的js无法执行的解决办法
2007/02/25 Javascript
关于js中alert弹出窗口文本换行问题简单详细说明
2012/12/11 Javascript
jQuery点击tr实现checkbox选中的方法
2013/03/19 Javascript
JS控制图片等比例缩放的示例代码
2013/12/24 Javascript
node-webkit打包成exe文件被360误报木马的解决方法
2015/03/11 Javascript
JQuery中$.each 和$(selector).each()的区别详解
2015/03/13 Javascript
详解AngularJS中的表达式使用
2015/06/16 Javascript
Bootstrap进度条组件知识详解
2016/05/01 Javascript
js带闹铃功能的倒计时代码
2016/09/29 Javascript
Bootstrap如何创建表单
2016/10/21 Javascript
JS在浏览器中解析Base64编码图像
2017/02/09 Javascript
微信小程序开发之toast提示插件使用示例
2017/06/08 Javascript
解决Layui数据表格中checkbox位置不居中的方法
2018/08/15 Javascript
vue-vuex中使用commit提交mutation来修改state的方法详解
2018/09/16 Javascript
在mpvue框架中使用Vant WeappUI组件库的注意事项【推进】
2019/06/09 Javascript
angularjs自定义过滤器demo示例
2019/08/24 Javascript
Python通过select实现异步IO的方法
2015/06/04 Python
Python画图实现同一结点多个柱状图的示例
2019/07/07 Python
Python 实现遥感影像波段组合的示例代码
2019/08/04 Python
Python实现子类调用父类的初始化实例
2020/03/12 Python
Django之choices选项和富文本编辑器的使用详解
2020/04/01 Python
Python之变量类型和if判断方式
2020/05/05 Python
Python3 用什么IDE开发工具比较好
2020/11/28 Python
Spartoo西班牙官网:法国时尚购物网站
2018/03/27 全球购物
自我评价个人范文
2013/12/16 职场文书
计算机专业应届生求职信
2014/04/06 职场文书
教师批评与自我批评材料
2014/10/16 职场文书
毕业答辩开场白范文
2015/05/27 职场文书
咖啡厅里的创业计划书
2019/08/21 职场文书
MySQL系列之开篇 MySQL关系型数据库基础概念
2021/07/02 MySQL
《Estab Life》4月6日播出 正式PV、主视觉图公开
2022/03/20 日漫