想給演算法/資料做個可玩的demo卻苦於找不到合適的工具?今天給大家分享的是bokeh,本篇將會手把手教你從零開始做出”線上、互動式、炫酷“的demo。
目錄鳥瞰bokeh三分鐘上手bokeh部署你的bokeh鳥瞰bokeh
Bokeh是一款強大的資料視覺化工具,具備以下五大優點:
靈活,簡單到複雜一網打盡,從簡單視覺化到各種複雜的樣式及互動式;可玩,各類元件幫助你互動式、動態地展示資料,觀眾一目瞭然;可共享,方便釋出到網頁、網站或者jupyter notebook,區別於pyQT等,網頁的形式方便分享並且可以隨時隨地執行和檢視;高效,使用起來非常高效,非常適合javascript用起來不太順手的人群(比如我),比起js裡的ZingCharts,ECharts等,個人還是傾向於熟悉的python,尤其是現在很多AI演算法都是基於python的,所以寫完演算法不用改動太多就可以用bokeh搭建demo,真香!強大,支援使用者使用javascript開發高階的功能。接下來,本篇從資料、圖形、互動、樣式四個角度層層遞進,帶你快速上手bokeh!
三分鐘上手bokeh
必須強調的是,教程有多麼詳細可能都比不上自己認真讀一下官方手冊,但是這篇分享的目的在於作為一個拋磚引玉的作用,幫你快速建立對這套框架的關鍵元素、流程、細節的認知。
資料
資料是核心,bokeh支援直接使用list、numpy、pandas(這三種大家都比較熟悉),另外,內部提供ColumnDataSource,掌握了這個介面大部分圖就可以畫了,優勢在於可以實現多個圖形之間的資料共享,基本使用方法如下:
from bokeh.plotting import figurefrom bokeh.models import ColumnDataSourcesource = ColumnDataSource(data={'x_values': [1, 2, 3, 4, 5], 'y_values': [6, 7, 2, 3, 6]})p = figure()p.circle(x='x_values', y='y_values', source=source)
除此之外,值得一提的還有網路資料結構以及地圖資料結構,網路資料結構的基本元素包括:
節點樣式(形狀、顏色)節點索引邊節點的實際位置 (橫縱座標)一起來過一遍官方的例程(註釋在每一句末尾):
import mathfrom bokeh.models import Ellipse, GraphRenderer, StaticLayoutProviderfrom bokeh.palettes import Spectral8from bokeh.plotting import figureN = 8 # 8個節點node_indices = list(range(N)) # 節點索引從0到7graph = GraphRenderer() graph.node_renderer.data_source.add(node_indices, 'index') # 新增索引graph.node_renderer.data_source.add(Spectral8, 'color') # 新增顏色graph.node_renderer.glyph = Ellipse(height=0.1, width=0.2, fill_color='color') # 節點樣式為橢圓graph.edge_renderer.data_source.data = dict(start=[0]*N, end=node_indices) # 邊, 起點索引對應終點索引即為一條邊circ = [i*2*math.pi/8 for i in node_indices]x = [math.cos(i) for i in circ] # 節點的橫座標y = [math.sin(i) for i in circ] # 節點縱座標graph_layout = dict(zip(node_indices, zip(x, y)))graph.layout_provider = StaticLayoutProvider(graph_layout=graph_layout) # 給節點新增位置資訊
地圖資料結構——資料支援谷歌地圖、CartoDB,座標支援墨卡託投影、經緯度等。這裡不展開贅述。
圖形
圖形的種類非常齊全,包含線、點、柱、熱圖、餅圖、地圖等,如下圖:
圖形方面bokeh基本類似於matplotlib,圖的各種引數可以在figure中配置,例如圖的尺寸大小、橫縱座標範圍等,一個圖可以包含多種圖形,圖形引數可以查閱手冊,關於具體的圖形如何繪製建議查閱官方的相簿及示範程式碼。這裡講一個常用但是容易踩坑的點——figure載入圖片,注意點包括載入方式、縱座標形式兩點。
載入方式。bokeh除了可以繪製二維資料為影象之外,也可以從圖片檔案載入,如果是本地執行bokeh,可以用本地圖片的路徑也可以直接用圖片的超連結,但是如果是在伺服器執行bokeh,會報錯找不到本地圖片路徑,建議把圖片上傳到圖床,然後用圖床的超連結。(推薦圖床PicGo[3],支援Github圖床,親測有效)縱座標形式。區別於matplotlib裡的imshow縱座標索引預設從上到下,bokeh image預設縱座標索引為從下到上,這就導致二維資料在bokeh和matplotlib繪出的圖片會出現上下翻轉的現象。但是bokeh從檔案或者連結讀取圖片不會出現上下翻轉(此時縱座標索引依然預設從下到上)。(左matplotlib imshow,右bokeh image)互動
何為”可玩“?互動即可玩!本質是三個要素——物件、事件和回撥函式。bokeh提供的互動方式可以分為兩大類:
基本操作,主要是直接在圖上進行互動,例如矩形選擇、放大縮小、整體移動、滑鼠懸停;元件,例如文字框、按鈕、滑條、下拉框、多選框等,這些元件都可以用on_change等函式對應使用者自定義的響應,也可以用js_on_change關聯javascript函式。樣式
樣式分為三個層次:
圖形的樣式,例如顏色、尺寸等,這些都可以透過圖形的API進行設計,視覺化好看與否主要由這部分決定。多圖排版,如何放置多個圖也很關鍵,比如並排、網格等,可以使用gridplot()或者layout()快速實現美觀的排版。其他部分的樣式,除了這些圖片之外,很多情況下我們都需要一些相關的文字說明或者其他內容,bokeh支援將圖形嵌入到html當中,也就是說其他內容樣式可以藉助於html、css等進行靈活設計。具體怎麼做我們將在下一個部分講解。部署bokeh
有了bokeh程式之後如何部署到網站呢?方式有很多種,比如jupyter、Flask、Django、Apache等。這裡介紹快速、方便的一種形式——將bokeh server部署到binder。什麼是binder?簡單來講就是可以載入github上的jupyter notebook。輸入github連結、分支等資訊就可以線上跑起來jupyter。
那麼如何用binder跑起來我們的bokeh server呢,首先從[4]拉取這個模板,紅色是我們需要修改的檔案,一個是在yml需要宣告執行bokeh需要的包,比如bokeh等,另一個就是bokeh的主體——放置所有bokeh相關程式的資料夾。注意:這個倉庫裡的程式只給了獨立的py程式,也就是沒有html、css等。
要加入html和css檔案,檔案結構如下,也就是在bokeh-app/下面除了py檔案還加入了templates/,index.html檔案當中可以用{{super()}}的方式繼承main.py生成的bokeh所有元素。(也有其他形式,比如獨立生成script、div等元素,具體可以參照[5])
├── README.md├── bokeh-app│ ├── README.md│ ├── main.py│ └── templates│ ├── index.html│ └── styles.css├── bokehserverextension.py├── environment.yml└── postBuild
最後,只要把{username}和{repo-name}替換成github的使用者名稱和倉庫名就可以。
https://mybinder.org/v2/gh/{username}/{repo-name}/master?urlpath=/proxy/5006/bokeh-app
到這裡,我們就成功把bokeh部署到binder上啦!
今天的分享就到這裡啦,同系列未來會講解pyQT、matlab GUI等的使用。
參考文獻
[1] https://bokeh.org/
[2] https://mybinder.org/
[3] https://github.com/Molunerfinn/PicGo
[4] https://github.com/binder-examples/bokeh
[5] https://github.com/bokeh/bokeh/tree/branch-2.3/examples/app/gapminder