[譯] 利用 Python中的 Bokeh 實現數據可視化,第三部分:製做一個完整的儀表盤

在 Bokeh 中建立交互式可視化應用程序html

有時我會利用數據科學來解決特定問題。其餘時候,我會嘗試一種新工具,好比說 Bokeh ,由於我在 Twitter 上看到一些很酷的項目,就會想:「那看起來很棒。雖然我不肯定何時會用到,但早晚會有用的。」幾乎每次我都這麼說,可是我最終都會找到這個工具的用途。 數據科學須要你掌握許多不一樣方面的知識,你永遠不會知道下一個你將使用的想法未來自哪裏!前端

做爲一名數據科學研究人員,在試用了幾個星期以後,我終於在 Bokeh 的例子中找到了一個完美的用例。個人研究項目 涉及利用數據科學提升商業建築的能源效率。在最近的一次會議上,咱們須要用一種方法來展現咱們使用的衆多技術的成果。一般狀況下都建議使用 powerpoint 來完成這項任務,可是效果並不明顯。大多數在會議中的人在看到第三張幻燈片時,就已經失去耐心了。儘管我對 Bokeh 還不是很熟悉,但我仍然自願嘗試利用這個庫作一個交互式應用程序,我認爲這會擴展個人技能,創造一個吸引人的方式來展現咱們的項目。安全起見,咱們團隊準備了一個演示的備份,但在我向他們展現了一部分初稿以後,他們便給予了所有支持。最終的交互式儀表板在會議中脫穎而出,將來咱們的團隊也將會使用:python

個人研究構建的 Bokeh 儀表盤的例子android

雖說並非每個你在 Twitter上看到的想法均可能對你的職業生涯產生幫助,但我能夠負責的說,瞭解更多的數據科學技術不會有什麼壞處。 沿着這些思路,我開始了本系列文章,以展現 Bokeh 的功能, Bokeh 是 Python 中一個強大的繪圖庫,他可讓你製做交互式繪圖和儀表盤。儘管我不能向你展現有關我研究的儀表盤,可是我可使用一個公開的數據集展現在 Bokeh 中構建可視化的基礎知識。第三篇文章是個人 Bokeh 系列文章的延續,第一部分着重於構建一個簡單的圖第二部分展現如何向 Bokeh 圖中添加交互。在這篇文章中,咱們將看到如何設置一個完整的 Bokeh應用程序,並在您的瀏覽器中運行可訪問的本地Bokeh服務器!ios

本文將重點介紹 Bokeh 應用程序的結構,而不是具體的細節,可是你能夠在 GitHub 上找到全部內容的完整代碼。咱們將會使用 NYCFlights13 數據集,這是一個 2013 年從紐約 3 個機場起飛的航班的真實信息數據集。這個數據集中有超過 300,000 個航班信息,對於咱們的儀表盤,咱們將主要關注於到達延遲信息的統計。git

爲了能完整運行整個應用程序,你須要先確保你已經安裝了 Bokeh(使用 pip install bokeh),從 GitHub上 下載 [bokeh_app.zip](https://github.com/WillKoehrsen/Bokeh-Python-Visualization/blob/master/bokeh_app.zip) 文件夾, 解壓,並在當前目錄打開一個命令窗口,並輸入 bokeh serve --show bokeh_app。這會設置一個 Bokeh 的本地服務 同時還會在你的瀏覽器中打開一個應用(固然你也可使用 Bokeh 的在線服務,可是目前對咱們來講本地主機足矣)。github

最終產品

在咱們深刻討論細節以前,讓咱們先來看看咱們的最終產品,這樣咱們就能夠看到各個部分是如何組合在一塊兒的。下面是一個短片,展現了咱們如何與完整的儀表盤互動:web

Bokeh 航班應用最終版後端

我在本地服務器上運行的瀏覽器(在Chrome的全屏模式下)中使用 Bokeh 應用程序。在頂部咱們看到許多選項卡,每一個選項卡包含不一樣部分的應用程序。儀表盤的想法是,雖然每一個選項卡能夠獨立存在,可是咱們能夠將其中許多選項卡鏈接在一塊兒,以支持對數據的完整探索。這段視頻展現了咱們能夠用 Bokeh 製做的圖表的範圍,從直方圖和密度圖,到能夠按列排序的數據表,再到徹底交互式的地圖。使用 Bokeh 這個庫除了能夠建立豐富的圖形外,另外一個好處是交互。每一個標籤都有一個交互元素可讓用戶參與到數據中,並本身探索。從經驗來看,當探索一個數據集時,人們喜歡本身去洞察,咱們可讓他們經過各類控件來選擇和過濾數據。瀏覽器

如今咱們對目標儀表盤已經有一個概念了,接下來讓咱們看看如何建立 Bokeh 應用程序。 我強烈建議你下載這些代碼,以供參考!


Bokeh 應用的結構

在編寫任何代碼以前,爲咱們的應用程序創建一個框架是很重要的。在任何項目中,很容易被編碼衝昏頭腦,很快就會迷失在一堆還沒有完成的腳本和錯位的數據文件中,所以咱們想要在編寫代碼和插入數據前先建立一個框架。這個組織將幫助咱們跟蹤應用程序中的全部元素,並在不可避免地出錯時幫助咱們進行調試。此外,咱們能夠在將來的項目中複用這個框架,這樣咱們在規劃階段的初始投資將在將來獲得回報。

爲了設置一個 Boken 應用,我建立了一個名爲bokeh_app的根目錄來保存全部內容。 在這個目錄中,咱們建立了一個子目錄用來存檔數據(命名爲 data ),另外一個子目錄用來存放腳本文件(命名爲 script )並經過一個 main.py 文件將全部的東西組合在一塊兒.。一般,爲了管理全部代碼,我發現最好將每一個選項卡的代碼保存在單獨的 Python 腳本中,並從單個主腳本調用它們。下面是我爲 Bokeh 應用程序所建立的文件結構,它改編自官方文檔

bokeh_app
|
+--- data
|   +--- info.csv
|   +--- info2.csv
|
+--- scripts
|   +--- plot.py
|   +--- plot2.py
|
+--- main.py
複製代碼

對於 flight 應用程序,其結構大體以下:

航班儀表盤的文件夾結構

bokeh_app 目錄下有三個主要部分: data, scripts, 和 main.py。當須要運行服務器時,咱們在 bokeh_app 目錄運行 Bokeh ,它會自動搜索並運行 main.py 腳本。有了整體結構以後,讓咱們來看看 main.py 文件,我把它稱爲 Bokeh 應用程序的啓動程序(並非專業術語)!

main.py

main.py 腳本是 Bokeh 應用程序的啓動腳本。它加載數據,並把傳遞給其餘腳本,獲取結果圖,並將它們組織好後單個顯示出來。這將是我展現的惟一一個完整的腳本,由於它對應用程序很是重要:

# Pandas for data management
import pandas as pd

# os methods for manipulating paths
from os.path import dirname, join

# Bokeh basics 
from bokeh.io import curdoc
from bokeh.models.widgets import Tabs


# Each tab is drawn by one script
from scripts.histogram import histogram_tab
from scripts.density import density_tab
from scripts.table import table_tab
from scripts.draw_map import map_tab
from scripts.routes import route_tab

# Using included state data from Bokeh for map
from bokeh.sampledata.us_states import data as states

# Read data into dataframes
flights = pd.read_csv(join(dirname(__file__), 'data', 'flights.csv'), 
	                                          index_col=0).dropna()

# Formatted Flight Delay Data for map
map_data = pd.read_csv(join(dirname(__file__), 'data', 'flights_map.csv'),
                            header=[0,1], index_col=0)

# Create each of the tabs
tab1 = histogram_tab(flights)
tab2 = density_tab(flights)
tab3 = table_tab(flights)
tab4 = map_tab(map_data, states)
tab5 = route_tb(flights)

# Put all the tabs into one application
tabs = Tabs(tabs = [tab1, tab2, tab3, tab4, tab5])

# Put the tabs in the current document for display
curdoc().add_root(tabs)
複製代碼

咱們從必要的導包開始,包括建立選項卡的函數,每一個選項卡都存儲在 scripts 目錄中的單獨腳本中。若是你看下文件結構,注意這裏有一個 __init__.py 文件在 scripts 目錄中。這是一個徹底空白的文件,須要放在目錄中,以容許咱們使用相對語句導入適當的函數 (例如 from scripts.histogram import histogram_tab ).我不太清楚爲何須要這樣作,但它確實有效(我曾經解決過這個問題,這裏是 Stack Overflow的答案).

在導入庫和腳本後,咱們利用 Python [__file__](https://stackoverflow.com/questions/9271464/what-does-the-file-variable-mean-do/9271617) 屬性讀取必要的數據。在本例中,咱們使用了兩個 pandas 數據框(flightsmap_data )以及包含在 Bokeh 中的美國各州的數據。讀取數據以後,腳本繼續進行執行:它將適當的數據傳遞給每一個函數,每一個函數繪製並返回一個選項卡,主腳本將全部這些選項卡組織在一個稱爲 tabs 的佈局中。做爲這些獨立選項卡函數的示例,讓咱們來看看繪製 map_tab 的函數。

該函數接收 map_data (航班數據的格式化版本)和美國各州數據,併爲選定的航空公司生成航線圖:

地圖選項卡

咱們在本系列的第 2 部分中介紹了交互式情節,而這個情節只是該思想的一個實現。功能總體結構爲:

def map_tab(map_data, states):
    ...
    
    def make_dataset(airline_list):
    ...
       return new_src
    def make_plot(src):
    ...
       return p

   def update(attr, old, new):
   ...
      new_src = make_dataset(airline_list)
      src.data.update(new_src.data)

   controls = ...
   tab = Panel(child = layout, title = 'Flight Map')
   
   return tab
複製代碼

咱們看到了熟悉的 make_dataset, make_plot, 和 update 函數,這些函數用於[使用交互式控件繪製繪圖](towardsdatascience.com/data- visualiz-with - bokehin - pythonpart -ii-interactions-a4cf994e2512)。一旦咱們設置好了圖,最後一行將整個圖返回給主腳本。每一個單獨的腳本(5個選項卡對應5個選項卡)都遵循相同的模式。

回到主腳本,最後一步是收集選項卡並將它們添加到一個單獨的文檔中。

# Put all the tabs into one application
tabs = Tabs(tabs = [tab1, tab2, tab3, tab4, tab5])

# Put the tabs in the current document for display
curdoc().add_root(tabs)
複製代碼

選項卡顯示在應用程序的頂部,就像任何瀏覽器中的選項卡同樣,咱們能夠輕鬆地在它們之間切換以查看數據。

運行 Bokeh 服務

在完成全部的設置和編碼以後,在本地運行 Bokeh 服務器很是簡單。咱們打開一個命令行界面(我更喜歡 Git Bash,但任何一個均可以),切換到包含 bokeh_app 的目錄,並運行 bokeh serve --show bokeh_app 。假設全部代碼都正確,應用程序將自動在瀏覽器中打開地址 http://localhost:5006/bokeh_app 。而後,咱們就能夠訪問應用程序並查看咱們的儀表盤了!

Bokeh 航班應用最終版

在 Jupyter Notebook 中調試

若是出了什麼問題(在咱們剛開始編寫儀表盤的時候,確定會出現這種狀況),使人沮喪的是,咱們必須中止服務器、對文件進行更改並從新啓動服務器,以查看咱們的更改是否達到了預期的效果。爲了快速迭代和解決問題,我一般在 Jupyter Notebook 中開發圖。Jupyter Notebook 對 Bokeh 來講是一個很好的開發環境,由於你能夠在筆記本中建立和測試徹底交互式的繪圖。語法略有不一樣,但一旦你有了一個完整的圖,代碼只需稍加修改,就能夠複製粘貼到一個獨立的 .py 腳本。要了解這一點的實際應用,請查看 [Jupyter Notebook](github.com/willkoehrse… - pyth-visualization/blob/master/application/app_development .ipynb)。


總結

一個徹底可交互式的 Bokeh 儀表盤可使任何數據科學項目脫穎而出。我常常看到個人同事們作了不少很是棒的統計工做,但卻不能清楚地表達其結果,這意味着全部這些工做都沒有獲得應有的承認。從我的經驗來看,我認爲 Bokeh 應用程序在交流結果方面很是麼有效。雖然製做一個完整的儀表板須要作不少工做(超過600行代碼),但其結果是值得的。此外,一旦咱們有了一個應用程序,咱們就可使用 GitHub 快速地共享它,若是咱們對咱們的結構很瞭解,咱們就能夠在其餘項目中重用這個框架。

從這個項目中得出的關鍵點適用於許多常規數據科學項目:

  1. 在開始一項數據科學任務以前,擁有適當的框架/結構( Bokeh 或其餘的框架)是相當重要的。這樣,您就不會發現本身迷失在試圖查找錯誤的代碼森林中。並且,一旦咱們開發了一個有效的框架,它就能夠以最小的工做量被複用,從而在將來帶來收益。
  2. 找到一個調試周期,使你可以快速進行想法迭代是相當重要的。 Jupyter Notebook 支持編寫代碼—查看結果—修復錯誤的循環,這有助於提升開發週期的效率(至少對於小型項目來講是這樣)。
  3. Bokeh 中的交互式應用程序將提高您的項目並鼓勵用戶參與。儀表盤能夠是獨立的探索性項目,也能夠突出顯示你已經完成的全部艱難的分析工做!
  4. 你永遠不知道在哪裏能夠找到下一個你在工做中能用到的或有幫助的工具。因此睜大你的眼睛,不要懼怕嘗試新的軟件和技術!

這就是本文和本系列的所有內容,儘管我計劃在將來在額外發布有關 Bokeh 的獨立教程。以一種使人信服的方式展現數據科學成果是相當重要的,有了像 Bokeh 和 plot.ly 這樣的庫,製做交互式圖形變得愈來愈容易。你能夠在 Bokeh GitHub repo 查看我全部的工做,免費 fork 它並開始你本身的項目。如今,我渴望看到其餘人能創造出什麼!

一如既往地,我歡迎反饋和建設性的批評。你能夠經過Twitter @koehrsen_will聯繫到我。


  1. [譯] 利用 Python中的 Bokeh 實現數據可視化,第一部分:入門
  2. [譯] 利用 Python中的 Bokeh 實現數據可視化,第二部分:交互
  3. [譯] 利用 Python中的 Bokeh 實現數據可視化,第三部分:製做一個完整的儀表盤

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索