Python如何使用bokeh包和geojson數(shù)據(jù)繪制地圖
最近要繪制倫敦區(qū)地圖,查閱了很多資料后最終選擇使用bokeh包以及倫敦區(qū)的geojson數(shù)據(jù)繪制。
bokeh是基于python的繪圖工具,可以繪制各種類型的圖表,支持geojson數(shù)據(jù)的讀取及繪制地圖。
安裝bokeh
$ pip install bokeh
軟件版本
python-3.7.7bokeh-2.0.0
數(shù)據(jù)來源
倫敦地圖數(shù)據(jù)來源于Highmaps地圖數(shù)據(jù)集。下載的是英國的地圖數(shù)據(jù)united-kindom.geo.json。需要對得到的數(shù)據(jù)進行預處理才能得到只含倫敦地區(qū)的數(shù)據(jù)。這需要對geojson數(shù)據(jù)的格式有一定的了解。在對數(shù)據(jù)進行處理之前,先看如何繪制英國地圖。
繪制英國地圖
from bokeh.plotting import curdoc, figure
from bokeh.models import GeoJSONDataSource
# 讀入英國地圖數(shù)據(jù)并傳給GeoJSONDataSource
with open("united-kindom.geo.json", encoding="utf8") as f:
geo_source = GeoJSONDataSource(geojson=f.read())
# 設置一張畫布
p = figure(width=500, height=500)
# 使用patches函數(shù)以及geo_source繪制地圖
p.patches(xs='xs', ys='ys', source=geo_source)
curdoc().add_root(p)
上述代碼可以繪制出英國地圖。將上述代碼保存為test.py,在終端運行
$ bokeh serve --show test.py
這會自動打開瀏覽器,并顯示英國地圖。
運行結果如圖:

獲取倫敦地區(qū)數(shù)據(jù)
獲取倫敦地區(qū)數(shù)據(jù)可以手動從united-kingdom.geo.json文件中篩選出倫敦的數(shù)據(jù),也可以先用python先把數(shù)據(jù)過濾一遍,然后將數(shù)據(jù)傳給bokeh。這需要對geojson文件格式有一定的了解,在此不詳細介紹。
from bokeh.plotting import curdoc, figure
from bokeh.models import GeoJSONDataSource
import json
# 用json庫讀取數(shù)據(jù)
with open("united-kindom.geo.json", encoding="utf8") as f:
data = json.loads(f.read())
# 判斷是不是倫敦地區(qū)數(shù)據(jù)
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
# 過濾數(shù)據(jù)
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)
運行結果如圖:

美化
上面的倫敦地圖只是一個大概的輪廓,下面對地圖添加一系列功能。
添加各區(qū)輪廓線
p.patches(xs='xs', ys='ys', fill_alpha=0.7, # 畫輪廓線
line_color='white', # 線的顏色
line_width=0.5, # 線的寬度
source=geo_source)
現(xiàn)在地圖區(qū)域輪廓很清晰。
添加顏色
# 為每一個地區(qū)增加一個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"對應每個地區(qū)的color屬性
source=geo_source)
現(xiàn)在地圖五顏六色。
增加圖注
import random
# 隨機產(chǎn)生數(shù)據(jù)用于展示
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是數(shù)據(jù)中原本有的,number是新近添加的。
)
現(xiàn)在鼠標放到區(qū)域上時,會顯示"區(qū)域名, number: 數(shù)字"。
去掉坐標軸與背景線
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)
倫敦地圖完成了

總結
最開始想用pyecharts做的,但是pyecharts并沒有倫敦的地圖。折騰半天,最后只好自己找geojson數(shù)據(jù)來畫地圖。
找到了很多關于地圖的數(shù)據(jù)和工具,比如上文中提到的highmap數(shù)據(jù)集,以及DataV.altas,這個工具可以可視化地提取中國區(qū)域的地圖數(shù)據(jù),但感覺比起自己找數(shù)據(jù),畫中國地圖還是pyecharts來得實在。
數(shù)據(jù)最重要。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
基于python實現(xiàn)數(shù)組格式參數(shù)加密計算
這篇文章主要介紹了基于python實現(xiàn)數(shù)組格式參數(shù)加密計算,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04
python使用Flask操作mysql實現(xiàn)登錄功能
這篇文章主要介紹了python使用Flask操作mysql實現(xiàn)登錄功能,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-05-05
python如何把字符串類型list轉(zhuǎn)換成list
這篇文章主要介紹了python如何吧字符串類型list轉(zhuǎn)換成list,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-02-02
python 函數(shù)內(nèi)部修改外部變量的方法
今天小編就為大家分享一篇python 函數(shù)內(nèi)部修改外部變量的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
利用pytorch實現(xiàn)對CIFAR-10數(shù)據(jù)集的分類
今天小編就為大家分享一篇利用pytorch實現(xiàn)對CIFAR-10數(shù)據(jù)集的分類,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
用Q-learning算法實現(xiàn)自動走迷宮機器人的方法示例
這篇文章主要介紹了用Q-learning算法實現(xiàn)自動走迷宮機器人的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-06-06

