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删除nginx缓存文件示例(python文件操作)
Mar 26 Python
python实现DNS正向查询、反向查询的例子
Apr 25 Python
Python使用urllib2模块实现断点续传下载的方法
Jun 17 Python
python模块之paramiko实例代码
Jan 31 Python
django富文本编辑器的实现示例
Apr 10 Python
详解爬虫被封的问题
Apr 23 Python
Python使用gluon/mxnet模块实现的mnist手写数字识别功能完整示例
Dec 18 Python
python读取tif图片时保留其16bit的编码格式实例
Jan 13 Python
python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例
Feb 27 Python
使用python实现微信小程序自动签到功能
Apr 27 Python
Python 字符串池化的前提
Jul 03 Python
python中如何打包用户自定义模块
Sep 23 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中的观察者模式
2010/03/24 PHP
谈谈关于php的优点与缺点
2013/04/11 PHP
基于Discuz security.inc.php代码的深入分析
2013/06/03 PHP
codeigniter中实现一次性加载多个view的方法
2015/03/20 PHP
详解PHP中的PDO类
2015/07/06 PHP
使用phpstorm和xdebug实现远程调试的方法
2015/12/29 PHP
php微信高级接口调用方法(自定义菜单接口、客服接口、二维码)
2016/11/28 PHP
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
Javascript动态创建div的方法
2015/02/09 Javascript
深入理解JavaScript系列(44):设计模式之桥接模式详解
2015/03/04 Javascript
JS如何设置cookie有效期为当天24点并弹出欢迎登陆界面
2016/08/04 Javascript
bootstrap datetimepicker控件位置异常的解决方法
2017/11/23 Javascript
JS实现遍历不规则多维数组的方法
2018/03/21 Javascript
jQuery实现根据身份证号获取生日、年龄、性别等信息的方法
2019/01/09 jQuery
js实现网页同时进行多个倒计时功能
2019/02/25 Javascript
Python中splitlines()方法的使用简介
2015/05/20 Python
tensorflow实现加载mnist数据集
2018/09/08 Python
python实现动态创建类的方法分析
2019/06/25 Python
python3获取url文件大小示例代码
2019/09/18 Python
python根据时间获取周数代码实例
2019/09/30 Python
Pytorch转keras的有效方法,以FlowNet为例讲解
2020/05/26 Python
python绘制雷达图实例讲解
2021/01/03 Python
Python实现区域填充的示例代码
2021/02/03 Python
CSS3实现点击放大的动画实例代码
2017/02/27 HTML / CSS
HTML5在a标签内放置块级元素示例代码
2013/08/23 HTML / CSS
Maje德国官网:法国女性成衣品牌
2017/02/10 全球购物
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
super关键字的用法
2012/04/10 面试题
领导的自我鉴定
2013/12/28 职场文书
考试作弊被抓检讨书
2014/01/10 职场文书
表彰先进的通报
2014/01/31 职场文书
师德个人剖析材料
2014/02/02 职场文书
书香校园活动方案
2014/02/28 职场文书
新闻报道策划方案
2014/06/11 职场文书
物业工程部主管岗位职责
2015/04/16 职场文书
2019年怎样才能撰写出优秀的自荐信
2019/03/25 职场文书