Linux中國

使用 Bokeh 為你的 Python 繪圖添加交互性

在這一系列文章中,我通過在每個 Python 繪圖庫中製作相同的多條形繪圖,來研究不同 Python 繪圖庫的特性。這次我重點介紹的是 Bokeh(讀作 「BOE-kay」)。

Bokeh 中的繪圖比其它一些繪圖庫要複雜一些,但付出的額外努力是有回報的。Bokeh 的設計既允許你在 Web 上創建自己的互動式繪圖,又能讓你詳細控制交互性如何工作。我將通過給我在這個系列中一直使用的多條形圖添加工具提示來展示這一點。它繪製了 1966 年到 2020 年之間英國選舉結果的數據。

![](/data/attachment/album/202006/18/164745tbgswq11b3qqqito.png "A zoomed-in view on the plot")

繪圖的放大視圖(©2019 年 Anvil

製作多條形圖

在我們繼續之前,請注意你可能需要調整你的 Python 環境來讓這段代碼運行,包括以下:

  • 運行最新版本的 Python (在 LinuxMacWindows 上的說明)
  • 確認你運行的 Python 版本能與這些庫一起工作。

數據可在線獲得,可以用 Pandas 導入。

import pandas as pd
df = pd.read_csv('https://anvil.works/blog/img/plotting-in-python/uk-election-results.csv')

現在我們可以繼續進行了。

為了做出多條形圖,你需要對你的數據進行一下調整。

原始數據是這樣的:

>> print(long)
        year         party  seats
0       1966  Conservative    253
1       1970  Conservative    330
2   Feb 1974  Conservative    297
3   Oct 1974  Conservative    277
4       1979  Conservative    339
..       ...           ...    ...
103     2005        Others     30
104     2010        Others     29
105     2015        Others     80
106     2017        Others     59
107     2019        Others     72

[60 rows x 3 columns]

你可以把數據看成是每一個可能的 (year, party) 組合的一系列 seats 值。這正是 Bokeh 處理的方式。你需要做一個 (year, party) 元組的列表:

# 得到每種可能的 (year, party) 組合的元組
x = [(str(r[1]['year']), r[1]['party']) for r in df.iterrows()]

# This comes out as [('1922', 'Conservative'), ('1923', 'Conservative'), ... ('2019', 'Others')]

這些將是 x 值。y 值就是席位(seats)。

y = df['seats']

現在你的數據看起來應該像這樣:

x                               y
('1966', 'Conservative')        253
('1970', 'Conservative')        330
('Feb 1974', 'Conservative')    297
('Oct 1974', 'Conservative')    277
('1979', 'Conservative')        339
 ...      ...                   ...
('2005', 'Others')              30
('2010', 'Others')              29
('2015', 'Others')              80
('2017', 'Others')              59
('2019', 'Others')              72

Bokeh 需要你將數據封裝在它提供的一些對象中,這樣它就能給你提供交互功能。將你的 xy 數據結構封裝在一個 ColumnDataSource 對象中。

    from bokeh.models import ColumnDataSource

    source = ColumnDataSource(data={'x': x, 'y': y})

然後構造一個 Figure 對象,並傳入你用 FactorRange 對象封裝的 x 數據。

    from bokeh.plotting import figure
    from bokeh.models import FactorRange

    p = figure(x_range=FactorRange(*x), width=2000, title="Election results")

你需要讓 Bokeh 創建一個顏色表,這是一個特殊的 DataSpec 字典,它根據你給它的顏色映射生成。在這種情況下,顏色表是一個簡單的黨派名稱和一個十六進位值之間的映射。

    from bokeh.transform import factor_cmap

    cmap = {
        'Conservative': '#0343df',
        'Labour': '#e50000',
        'Liberal': '#ffff14',
        'Others': '#929591',
    }
    fill_color = factor_cmap('x', palette=list(cmap.values()), factors=list(cmap.keys()), start=1, end=2)

現在你可以創建條形圖了:

    p.vbar(x='x', top='y', width=0.9, source=source, fill_color=fill_color, line_color=fill_color)

Bokeh 圖表上數據的可視化形式被稱為「 字形 glyphs 」,因此你已經創建了一組條形字形。

調整圖表的細節,讓它看起來像你想要的樣子。

    p.y_range.start = 0
    p.x_range.range_padding = 0.1
    p.yaxis.axis_label = 'Seats'
    p.xaxis.major_label_orientation = 1
    p.xgrid.grid_line_color = None

最後,告訴 Bokeh 你現在想看你的繪圖:

   from bokeh.io import show

   show(p)

這將繪圖寫入一個 HTML 文件,並在默認的 Web 瀏覽器中打開它。如下結果:

![](/data/attachment/album/202006/18/164747njmjfybwkbb9jlgv.png "A multi-bar plot in Bokeh")

Bokeh 中的多條形繪圖(©2019年Anvil

它已經有了一些互動功能,比如盒子縮放。

![](/data/attachment/album/202006/18/164826c8yyefswvspee6v6.gif "Bokeh's built-in box zoom")

Bokeh 內置的盒子縮放(©2019Anvil

但 Bokeh 的厲害之處在於你可以添加自己的交互性。在下一節中,我們通過在條形圖中添加工具提示來探索這個問題。

給條形圖添加工具提示

要在條形圖上添加工具提示,你只需要創建一個 HoverTool 對象並將其添加到你的繪圖中。

    h = HoverTool(tooltips=[
        ('Seats', '@y'),
        ('(Year, Party)', '(@x)')
    ])
    p.add_tools(h)

參數定義了哪些數據會顯示在工具提示上。變數 @y@x 是指你傳入 ColumnDataSource 的變數。你還可以使用一些其他的值。例如,游標在圖上的位置由 $x$y 給出(與 @x@y 沒有關係)。

下面是結果:

![](/data/attachment/album/202006/18/164835yihiiitmiiwu5tpl.gif "The election graph, now with tooltips")

選舉圖,現在帶有工具提示(© 2019 Anvil

藉助 Bokeh 的 HTML 輸出,將繪圖嵌入到 Web 應用中時,你可以獲得完整的交互體驗。你可以在這裡把這個例子複製為 Anvil 應用(註:Anvil 需要註冊才能使用)。

現在,你可以看到付出額外努力在 Bokeh 中將所有數據封裝在 ColumnDataSource 等對象的原因了。作為回報,你可以相對輕鬆地添加交互性。

回歸簡單:Altair

Bokeh 是四大最流行的繪圖庫之一,本系列將研究它們各自的特別之處

我也在研究幾個因其有趣的方法而脫穎而出的庫。接下來,我將看看 Altair,它的聲明式 API 意味著它可以做出非常複雜的繪圖,而不會讓你頭疼。

via: https://opensource.com/article/20/5/bokeh-python

作者:Shaun Taylor-Morgan 選題:lujun9972 譯者:wxy 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    這個站點使用 Akismet 來減少垃圾評論。了解你的評論數據如何被處理

    More in:Linux中國

    Linux中國

    捐贈 Let's Encrypt,共建安全的互聯網

    隨著 Mozilla、蘋果和谷歌對沃通和 StartCom 這兩家 CA 公司處罰落定,很多使用這兩家 CA 所簽發證書的網站紛紛尋求新的證書籤發商。有一個非盈利組織可以為大家提供了免費、可靠和安全的 SSL 證書服務,這就是 Let's Encrypt 項目。現在,它需要您的幫助
    Linux中國

    關於Linux防火牆iptables的面試問答

    Nishita Agarwal是Tecmint的用戶,她將分享關於她剛剛經歷的一家公司(印度的一家私人公司Pune)的面試經驗。在面試中她被問及許多不同的問題,但她是iptables方面的專家,因此她想分享這些關於iptables的問題和相應的答案給那些以後可能會進行相關面試的人。 所有的問題和相應的答案都基於Nishita Agarwal的記憶並經過了重寫。 嗨,朋友!我叫Nishita Agarwal。我已經取得了理學學士學位,我的專業集中在UNIX和它的變種(BSD,Linux)。它們一直深深的吸引著我。我在存儲方面有1年多的經驗。我正在尋求職業上的變化,並將供職於印度的P
    Linux中國

    Lets Encrypt 已被所有主流瀏覽器所信任

    旨在讓每個網站都能使用 HTTPS 加密的非贏利組織 Lets Encrypt 已經得了 IdenTrust的交叉簽名,這意味著其證書現在已經可以被所有主流的瀏覽器所信任。從這個裡程碑事件開始,訪問者訪問使用了Lets Encrypt 證書的網站不再需要特別配置就可以得到 HTTPS 安全保護了。 Lets Encrypt 的兩個中級證書 ...