Bokeh 是一個支援 Python, R, 與 Lua 等程式語言的互動式資料視覺化開源套件, 具有縮放, 平移, 選取, 懸停提示等多種互動操作, 特別適合給資料工程師建立資料儀表板來展示探索性資料分析結果. Bokeh 套件其實就是將 Python 繪圖程式轉換成 HTML 和 Backeh.js 構成的前端網頁結構, 因此可以嵌入到網頁應用程式於瀏覽器中執行. Bokeh 採 BSD 授權開放原始碼, 可免費使用於商業用途.
參考書籍 :
- Python 網路爬蟲與資料視覺化 (旗標, 2018) 第 15 章
- Python 初學特訓班-增訂版 (碁峰, 2017) 第 7 章
- Python 數據可視化-基於 Bokeh 的可視化繪圖 (機械工業出版)
- Python programming for data analysis (Springer, 2021) 第 6 章
- Hands-On Data Visualization with Bokeh (Packt, 2019)
- Python Data Visualization Essentials Guide (BPB)
- Data Visualization with Python for Beginners (AI Publishing) 第 9 章
- Python Data Analysis 3rd (Packt, 2021)
- Interactive Data Visualization with Python 2nd (Packt, 2020)
- The Data Visualization Workshop (Packt, 2020)
1. 安裝 bokeh 套件 :
可使用 pip 或 pip3 (Linux) 安裝 Bokeh
pip install bokeh
我之前已安裝過 3.2.2 版 :
>>> import bokeh
>>> bokeh.__version__
'3.2.2'
所以加 -U 參數升版 :
pip install bokeh -U
D:\python\test>pip install bokeh -U
Requirement already satisfied: bokeh in c:\users\tony1\appdata\roaming\python\python310\site-packages (3.2.2)
Collecting bokeh
Downloading bokeh-3.7.3-py3-none-any.whl.metadata (12 kB)
Requirement already satisfied: Jinja2>=2.9 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from bokeh) (3.1.2)
Collecting contourpy>=1.2 (from bokeh)
Downloading contourpy-1.3.2-cp310-cp310-win_amd64.whl.metadata (5.5 kB)
Collecting narwhals>=1.13 (from bokeh)
Downloading narwhals-1.42.0-py3-none-any.whl.metadata (11 kB)
Requirement already satisfied: numpy>=1.16 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from bokeh) (1.24.3)
Requirement already satisfied: packaging>=16.8 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from bokeh) (24.2)
Requirement already satisfied: pandas>=1.2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from bokeh) (2.0.3)
Requirement already satisfied: pillow>=7.1.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from bokeh) (9.5.0)
Requirement already satisfied: PyYAML>=3.10 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from bokeh) (6.0.1)
Requirement already satisfied: tornado>=6.2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from bokeh) (6.3.3)
Requirement already satisfied: xyzservices>=2021.09.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from bokeh) (2023.7.0)
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from Jinja2>=2.9->bokeh) (2.1.3)
Requirement already satisfied: python-dateutil>=2.8.2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas>=1.2->bokeh) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas>=1.2->bokeh) (2023.3)
Requirement already satisfied: tzdata>=2022.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas>=1.2->bokeh) (2023.3)
Requirement already satisfied: six>=1.5 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from python-dateutil>=2.8.2->pandas>=1.2->bokeh) (1.16.0)
Downloading bokeh-3.7.3-py3-none-any.whl (7.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.0/7.0 MB 4.2 MB/s eta 0:00:00
Downloading contourpy-1.3.2-cp310-cp310-win_amd64.whl (221 kB)
Downloading narwhals-1.42.0-py3-none-any.whl (359 kB)
Installing collected packages: narwhals, contourpy, bokeh
Attempting uninstall: contourpy
Found existing installation: contourpy 1.1.0
Uninstalling contourpy-1.1.0:
Successfully uninstalled contourpy-1.1.0
Attempting uninstall: bokeh
Found existing installation: bokeh 3.2.2
Uninstalling bokeh-3.2.2:
Successfully uninstalled bokeh-3.2.2
Successfully installed bokeh-3.7.3 contourpy-1.3.2 narwhals-1.42.0
可見 Bokeh 本身很嬌小才 7MB 而已. 檢視版本 :
>>> import bokeh
>>> bokeh.__version__
'3.7.3'
可見已升至最新版.
2. Bokeh 的模組化結構 :
Bokeh 套件採模組化設計, 包含 14 個模組, 涵蓋從高階快速繪圖, 低階元件自訂, 排版, 輸出, 伺服器互動, 色彩方案, 範例資料到互動小部件等完整功能, 能滿足各種資料視覺化與互動應用. 這些模組共同構成了 Bokeh 強大且靈活的視覺化生態系 :
| Bokeh 模組名稱 | 說明 |
|---|---|
| bokeh.plotting | 高階繪圖 API, 可快速建立折線圖、長條圖、散點圖等常見圖表。 |
| bokeh.models | 低階元件系統, 提供資料來源、控制項與互動事件等物件。 |
| bokeh.layouts | 負責安排圖表與控制元件的位置, 支援 row、column 排版。 |
| bokeh.io | 圖表輸出與展示函式, 如 show(), output_file(), output_notebook() 等。 |
| bokeh.server | 建構 Bokeh Server Web 應用的基礎模組, 支援互動式資料更新。 |
| bokeh.application | 封裝多頁或模組化的 Bokeh Server 應用, 支援動態載入與初始化。 |
| bokeh.document | 管理 Bokeh Document 結構, 儲存所有圖表與元件的狀態。 |
| bokeh.themes | 套用主題樣式, 可自訂字型、顏色、背景等視覺樣式。 |
| bokeh.embed | 將 Bokeh 圖表嵌入 HTML、Flask、Jupyter 等應用環境。 |
| bokeh.resources | 控制 JS/CSS 資源載入方式, 如 inline 或 CDN 模式。 |
| bokeh.transform | 資料欄位轉換工具, 用於視覺映射如大小、顏色等動態設定。 |
| bokeh.palettes | 提供內建配色方案, 包含類別色系與連續漸層色系。 |
| bokeh.events | 自訂事件處理模組, 支援點擊、拖曳等使用者互動事件綁定。 |
| bokeh.util | 工具與內部函式庫, 包含除錯、類型檢查等開發輔助工具。 |
各模組之使用情境分類如下表 :
| 使用情境 | 建議使用模組 |
|---|---|
| 快速畫圖 | bokeh.plotting, bokeh.io |
| 建立儀表板 | bokeh.models, bokeh.layouts, bokeh.themes |
| 內嵌 HTML/Flask | bokeh.embed, bokeh.resources |
| Web App(伺服器端) | bokeh.server, bokeh.application, bokeh.document |
| 進階互動 | bokeh.events, bokeh.transform, bokeh.events |
| 開發輔助工具 | bokeh.util |
3. Bokeh 繪圖核心模組與 figure 物件的方法 :
對於一般繪圖應用而言, 最常使用到的 Bokeh 模組是下列三個核心模組 :
| Bokeh 核心模組 | 說明 |
|---|---|
| bokeh.plotting | 提供高階繪圖介面, 可快速建立常見圖表如折線圖, 長條圖, 散點圖等, 適合快速原型與互動視覺化. |
| bokeh.models | 提供低階物件系統, 控制圖表中的所有元件, 包含資料來源, 滑桿, 按鈕, 圖例, 工具提示等, 適合需要自訂互動邏輯的應用. |
| bokeh.layouts | 用於安排圖表與控制項的位置, 支援橫向 (row), 縱向 (column) 或巢狀排版, 是建立 Web 儀表板的重要工具. |
繪圖相關函式都放在 bokeh.plotting 模組裡, 最常用的是下表的四個函式 :
| bokeh.plotting 函式 | 說明 |
|---|---|
| figure() | 建立一個 figure 物件,並可設定標題、軸標籤、範圍、工具列等。 |
| output_file() | 指定輸出目標 HTML 檔案的檔名與標題,使得圖表可以儲存為網頁。 |
| show() | 顯示繪製好的圖形,一般會開啟瀏覽器來呈現 output_file() 所設定的 HTML。 |
| save() | 將圖形儲存為 HTML 檔案但不開啟瀏覽器,通常與 output_file() 搭配使用。 |
其中 figure() 函式是整個 Bokeh 繪圖程序的起點, 此函式之參數結構如下表 :
| figure() 參數 | 說明 |
|---|---|
| width | 設定圖形寬度(像素),預設為 600。 |
| height | 設定圖形高度(像素),預設為 600。 |
| title | 圖表標題,可為字串或 Title 物件。 |
| x_range | 指定 X 軸的範圍(如 [0, 10])或使用 Range1d、FactorRange。 |
| y_range | 指定 Y 軸的範圍,使用方式同 x_range。 |
| tools | 指定互動工具(如 "pan,wheel_zoom,reset")。 |
| x_axis_type | "linear"、"log"、"datetime" 或 "auto"。 |
| y_axis_type | "linear"、"log"、"datetime" 或 "auto"。 |
| toolbar_location | 工具列位置,"above"、"below"、"left"、"right" 或 None。 |
| background_fill_color | 背景色,可為顏色名稱 "red"、色碼 "#ff00ff" 或 "rgba(255, 0, 0, 0.5)"。 |
| sizing_mode | 響應式大小,常見值有 "fixed"、"stretch_width"、"scale_both" 等。 |
| match_aspect | 設為 True 時保持 x/y 軸比例一致。 |
| output_backend | "canvas"(預設)、"svg"、"webgl",指定繪圖後端。 |
除了畫布底色外, 在 Bokeh 中所有其他顏色相關的參數都可以用顏色名稱, 16 進位色碼, 以及 RGB 色碼這三種方法表示, RGB 色碼除了 "rgba(r, g, b, a)" 字串外也可以傳入 [r, g, b] 串列, 會自動將其轉成 "rgba(r, g, b)" 字串. 關於顏色名稱參考 :
figure() 函式沒有必要參數 (每個參數都有預設值), 呼叫 figure() 會傳回一個代表畫布的 figure 物件, 例如 :
>>> from bokeh.plotting import figure
>>> fig=figure()
>>> type(fig)
<class 'bokeh.plotting._figure.figure'>
figure 物件提供了許多方法可在畫布上繪製圖像元素 (Bokeh 稱為 glyph), 這些方法可分為主要繪圖之方法與輔助繪圖之方法兩類, 主要繪圖之方法說明如下表 :
| figure 物件繪圖方法 | 說明 |
|---|---|
| line() | 繪製折線圖, 必要參數 x, y 軸序列資料 |
| circle() | 繪製圓點圖(常用於散佈圖) |
| scatter() | 繪製散佈圖,可自訂標記樣式 |
| square() | 繪製方形點 |
| triangle() | 繪製三角形點 |
| diamond() | 繪製菱形點 |
| asterisk() | 繪製星號點 |
| x() | 繪製 X 標記 |
| cross() | 繪製十字標記 |
| circle_cross() | 圓形與十字混合標記 |
| circle_x() | 圓形與 X 混合標記 |
| square_cross() | 方形與十字混合標記 |
| square_x() | 方形與 X 混合標記 |
| rect() | 繪製矩形,可用於自訂長條圖 |
| vbar() | 繪製垂直條狀圖 |
| hbar() | 繪製水平條狀圖 |
| step() | 繪製階梯圖 |
| patch() | 繪製單個多邊形區域 |
| patches() | 繪製多個多邊形 |
| hex() | 六邊形點圖,常用於密度圖 |
| hex_tile() | 六邊形平鋪圖 |
| quad() | 四邊形,可用於 histogram 等 |
| ray() | 繪製射線圖 |
| segment() | 繪製線段(無箭頭) |
| wedge() | 繪製扇形,可用於圓餅圖 |
| annulus() | 繪製圓環圖 |
| annular_wedge() | 繪製環狀楔形圖 |
| image() | 以灰階形式繪製圖像資料 |
| image_rgba() | 以 RGBA 格式顯示影像 |
| image_url() | 嵌入網路圖片 |
| text() | 繪製文字標籤 |
| bezier() | 繪製貝茲曲線 |
| quadratic() | 繪製二次曲線 |
| arc() | 繪製弧形 |
| multi_line() | 繪製多條線 |
| multi_polygons() | 繪製多層多邊形,可包含內洞 |
除了上表之繪圖相關方法外, 還有一些是用來設定圖表, 佈局, 互動或處理事件的屬性與方法, 如下表所示 :
| figure 物件輔助方法/屬性 | 說明 |
|---|---|
| add_layout() | 新增圖例、標籤、顏色條、工具列等額外元素 |
| add_tools() | 新增互動工具(如滑鼠放大、選取工具) |
| on_event() | 綁定事件處理器(例如滑鼠點擊) |
| background_fill_color | 設定圖表背景顏色 |
| border_fill_color | 設定整個圖區外圍邊界顏色 |
| title | 設定或取得圖表標題 |
| x_range / y_range | 設定 X/Y 軸的範圍 |
| xaxis / yaxis | 取得或設定軸物件 |
| xgrid / ygrid | 取得或設定網格線 |
| legend | 取得或設定圖例 |
| toolbar_location | 設定工具列出現位置 : "above", "below", "left", None, "right" (預設) |
| title_location | 設定工具列出現位置 : "above"(預設), "below", "left", "right" |
其中 xgrid/ygrid 屬性分別是 X 軸與 Y 軸網格線 Grid 物件之串列, 每一個 Grid 物件都有一個 visible 屬性, 預設值為 True, 所以 Bokeh 繪製的圖預設都有網格線, 只要將其設為 False 即可取消網格線. 另外, figure() 函式與標題有關的參數只有 title, 標題位置必須用 figure 物件的 title_location 屬性來設定, 只有上下左右四個位置, 且上下是靠左, 不能置中.
其次 figure 物件還有一個常用屬性 legend, 其值是一個 Legend 物件串列, 可以利用 Legend 物件的 location 設定圖例的位置, 可用位置如下表 :
| legend.location 屬性值 | 說明 |
|---|---|
| "top_left" | 圖例顯示於圖表左上角 |
| "top_center" | 圖例顯示於圖表正上方中央 |
| "top_right" | 圖例顯示於圖表右上角 (預設) |
| "center_left" | 圖例顯示於圖表正中央偏左 |
| "center" | 圖例顯示於圖表正中央 |
| "center_right" | 圖例顯示於圖表正中央偏右 |
| "bottom_left" | 圖例顯示於圖表左下角 |
| "bottom_center" | 圖例顯示於圖表正下方中央 |
| "bottom_right" | 圖例顯示於圖表右下角 |
例如 :
fig.legend[0].location='top_left' # 圖例位置
fig.legend[0].background_fill_color='#fefbd8' # 圖例背景色
fig.legend.label_text_font_size='14pt' # 圖例文字大小
fig.legend.label_text_color= 'red' # 圖例文字顏色
xgrid/ygrid 屬性值為 Axis 軸物件, 可用來設定 X 軸與 Y 軸的外觀與行為, 例如調整字型, 旋轉標籤, 設定顏色, 隱藏顯示等, 常用的 Axis 物件屬性如下表 :
| xaxis / yaxis Axis 物件屬性 | 說明 |
|---|---|
| axis_label | 設定軸的標籤文字 (如 "時間", "價格") |
| visible | 控制軸是否顯示 (True / False) |
| major_label_orientation | 控制刻度文字方向,值可為 "horizontal"、"vertical" 或角度 (如 0.5) |
| axis_line_color | 設定軸線顏色,例如 "black"、"red" |
| axis_line_width | 設定軸線粗細 (單位為 px) |
| major_tick_line_color | 設定主刻度線顏色,若設為 None 表示不顯示 |
| minor_tick_line_color | 設定次刻度線顏色,預設為灰色,可設為 None |
| major_label_text_font_size | 刻度文字大小,例如 "12pt" |
| major_label_text_color | 刻度文字顏色,例如 "gray"、"blue" |
| axis_label_text_font_style | 標籤文字樣式,可為 "normal"、"italic"、"bold" |
例如 :
fig.xaxis.visible=False
fig.yaxis.visible=False
就會將 X 軸與 Y 軸隱藏起來了.
4. 用 Bokeh 繪製基本的互動圖表 :
用 Bokeh 繪圖很簡單, 只要四個步驟 :
- 匯入 bokeh.plotting 模組的 figure() 與 show() 函式
- 呼叫 figure() 函式建立 figure 物件
- 呼叫 figure 物件的繪圖方法
- 將 figure 物件傳給 show() 繪圖
例如繪製折線圖是呼叫 line() 方法, 必要參數是 X, Y 軸資料, 參數結構如下 :
| fig.line() 參數 | 說明 |
|---|---|
| x, y | x、y 資料(必要),可為 list、NumPy array、Pandas Series 等 |
| line_color | 線條顏色,如 "blue"、"#FF0000",預設為 "black" |
| line_width | 線條寬度(整數或浮點數),預設為 1 |
| line_dash | 虛線樣式,如 "solid"、"dashed"、'dotted', 'dotdash', 'dashdot' 等 |
| line_alpha | 線條透明度(0.0~1.0),預設為 1.0 |
| legend_label | 圖例標籤文字,設置後圖例會自動顯示此線 |
| muted | 是否初始為靜音(隱藏)狀態,配合 legend 的 mute 功能使用 |
| name | 為這條圖形指定名稱,可在 `select()` 搜尋用 |
| source | 提供一個 ColumnDataSource 作為資料來源 |
line_dash 參數也可以自訂虛線樣式, 方法是傳入一個整數串列, 其元素代表虛線中實線與空白的長度 (px), 例如 [6, 4] 表示 6px 實線, 4px 空白, 不斷重複.
例如 :
測試 1 : 預設無標記的折線圖 [看原始碼]
# bokeh-line-test-1.py
from bokeh.plotting import figure, show
x=[0, 1, 2, 3, 4, 5] # x 軸資料
y=[-5, -2, 6, 12, 4, 9] # y 軸資料
fig=figure() # 建立 figure 物件
fig.line(x, y) # 繪製折線圖
show(fig) # 顯示圖表
此例直接將 x, y 軸資料傳給 figure 物件的 line() 方法, 執行後預設會在目前工作目錄下產生一個與 Python 程式主檔名一樣的 .html 網頁檔, 並自動開啟瀏覽器顯示結果網頁 :
可見圖片右上角有一排互動按鈕, 其中下載按鈕可將所繪製之圖片下載存成 png 檔.
開啟工作目錄下的這個網頁檔會發現繪圖是由 bokeh-3.7.3.min.js 與一堆 JSON 資料完成的, 上面的 Python 程式主要就是生成這些 JSON 繪圖資料讓 bokeh-3.7.3.min.js 在畫布上繪圖 :
下面範例在呼叫 figure() 時傳入 width, height, 與 tiltle 參數設定圖片尺寸與標題, 同時設定折線圖線段的寬度與顏色 :
測試 2 : 設定圖片尺寸與折線圖的線段顏色與粗細 [看原始碼]
# bokeh-line-test-2.py
from bokeh.plotting import figure, show
x=[0, 1, 2, 3, 4, 5] # x 軸資料
y=[-5, -2, 6, 12, 4, 9] # y 軸資料
fig=figure(width=400, height=300, title='Bokeh 折線圖') # 建立 figure 物件
fig.line(x, y, line_width=4, line_color='red') # 繪製折線圖
show(fig) # 顯示圖表
結果如下 :
可見圖片尺寸從預設 600x600 變成 400x300 了, 圖表也有了標題 (預設位置為 left, 左上角), 且線段變成 4px 的紅色.
下面範例測試畫布的 toolbar_location 與 background_fill_color 參數, titil_location 參數, line() 方法的線段類型 (虛線) 與透明度 :
測試 3 : 設定圖片底色, 互動工具位置與線段類型, 透明度 [看原始碼]
# bokeh-line-test-3.py
from bokeh.plotting import figure, show
x=[0, 1, 2, 3, 4, 5] # x 軸資料
y=[-5, -2, 6, 12, 4, 9] # y 軸資料
fig=figure(
width=400,
height=300,
title='Bokeh 折線圖',
toolbar_location='left',
background_fill_color='ivory'
) # 建立 figure 物件
fig.title_location='below'
fig.line(
x,
y,
line_width=4,
line_dash='dashed',
line_alpha=0.5,
legend_label='測試資料'
) # 繪製折線圖
show(fig) # 顯示圖表
結果如下 :
可見互動工具變成放在左邊, 圖表標題改放置下方, 底色變成象牙色, 線段變成有透明度的虛線了.
下面範例測試將 fig.xgrid.visible/ fig.ygrid.visible 設為 False 取消網格線 :
測試 4 : 利用 fig.xgrid.visible/ fig.ygrid.visible 取消網格線 [看原始碼]
# bokeh-line-test-4.py
from bokeh.plotting import figure, show
x=[0, 1, 2, 3, 4, 5] # x 軸資料
y=[-5, -2, 6, 12, 4, 9] # y 軸資料
fig=figure(
width=400,
height=300,
title='Bokeh 折線圖',
toolbar_location='below',
background_fill_color='#ffff00' # 黃色
) # 建立 figure 物件
fig.xgrid.visible=False # 取消 x 軸網格線
fig.line(
x,
y,
line_width=4,
line_dash='dotted',
line_alpha=0.5,
legend_label='測試資料'
) # 繪製折線圖
show(fig) # 顯示圖表
此例僅取消 X 軸 (垂直) 網格線, 另外也將互動工具改放在底下, 虛線改為 dotted, 改用 16 進位色碼等, 結果如下 :





沒有留言 :
張貼留言