Linux中國

Python 下使用 Altair 數據製圖

Python 中的 繪圖庫 提供了呈現數據的多種方式,可以滿足你不同的偏好,如靈活性、布局、易用性,或者特殊的風格。

和其它方式相比,我發現,Altair 提供的是一種不同的解決方案,且總體而言使用起來更為簡單。得益於聲明式的繪圖語言 Vega,Altair 擁有一套優雅的介面,可以直接定義要繪的圖應該是什麼樣子,而不是通過寫一大堆循環和條件判斷去一步步構建。

繪圖流程

我通過繪製同一個多柱狀圖比較了多個 Python 繪圖庫的差異。正式開始之前,你需要將你的 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')

準備開始吧。為了做個比較,先看下面這個用 Matplotlib 做的圖:

![Matplotlib UK election results](/data/attachment/album/202008/06/110722oae6uu0zuu6bubv0.png "Matplotlib UK election results")

使用 Matplotlib 需要 16 行代碼,圖柱的位置需要自己計算。

使用 Altair 繪製相似的圖,代碼如下:

    import altair as alt

    chart = alt.Chart(df).mark_bar().encode(
        x='party',
        y='seats',
        column='year',
        color='party',
    )

    chart.save('altair-elections.html')

真是簡潔多了!與 Seaborn 類似,Altair 所用數據的組織形式是每個變數一列(即 數據列 )。這種方式下可以將每個變數映射到圖的一個屬性上 —— Altair 稱之為「通道」。在上例中,我們期望每個 「黨派」 在 x 軸上顯示為一組圖柱, 其 「席位」 顯示在 y 軸,且將圖柱按照 「年份」 分開為 「列」。我們還想根據 「黨派」 給圖柱使用不同的 「顏色」。用語言表述需求的話就是上面這個樣子,而這也正是代碼所要表述的!

現在把圖畫出來:

![Altair plot with default styling](/data/attachment/album/202008/06/110727ihauqasxq9h732as.png "Altair plot with default styling")

調整樣式

這和我們期待的效果有點接近了。與 Matplotlib 方案相比,主要區別在於 Altair 方案中,每個 year 組顯示的時候,內部之間都有個小空白 —— 這不是問題,這只是 Altair 多柱狀圖顯示的一個特性。

所以說呢,還需要對顯示樣式再做一些改進。

非整形數據

兩個不是整數的年份名稱(Feb 1974Oct 1974)顯示為 NaN 了。這可以通過將年份數值 year 轉換為字元串來解決:

    df['year'] = df['year'].astype(str)

指定數據排序方法

還需要讓 Altair 知道如何對數據進行排序。Altair 允許通過傳給它一個 Column 對象,來設定 Column 通道的更多細節。現在讓 Altair 按照數據在數據集中出現的順序排列:

    chart = alt.Chart(df).mark_bar().encode(
        # ...
        column=alt.Column('year', sort=list(df['year']), title=None),
        # ...
    )

移除坐標軸標籤

我們通過設置 title=None 移除了圖頂的 "year" 標籤。下面再一處每列數據的 "party" 標籤:

    chart = alt.Chart(df).mark_bar().encode(
        x=alt.X('party', title=None),
        # ...
    )

指定顏色圖

最後,我們還想自己指定圖柱的顏色。Altair 允許建立 domain 中數值與 range 中顏色的映射來實現所需功能,太貼心了:

    cmap = {
        'Conservative': '#0343df',
        'Labour': '#e50000',
        'Liberal': '#ffff14',
        'Others': '#929591',
    }

    chart = alt.Chart(df).mark_bar().encode(
        # ...
        color=alt.Color('party', scale=alt.Scale(domain=list(cmap.keys()), range=list(cmap.values())))
    )

樣式調整後的最終代碼

應用上述樣式調整之後,代碼看起來不那麼悅目了,但我們仍然是用聲明的方式實現的,這正是 Altair 如此有彈性的原因所在。實現過程中,仍然是使用的異於顯示數據的獨立變數來分離圖中不同屬性的,而不是像在 Matplotlib 中那樣直接對顯示數據做複雜的操作。唯一的不同是,我們的變數名字封裝在類似 alt.X() 的對象中,從而實現對顯示效果的控制:

    import altair as alt
    from votes import long as df

    cmap = {
        'Conservative': '#0343df',
        'Labour': '#e50000',
        'Liberal': '#ffff14',
        'Others': '#929591',
    }

    df['year'] = df['year'].astype(str)

    # We're still assigning, e.g. 'party' to x, but now we've wrapped it
    # in alt.X in order to specify its styling
    chart = alt.Chart(df).mark_bar().encode(
        x=alt.X('party', title=None),
        y='seats',
        column=alt.Column('year', sort=list(df['year']), title=None),
        color=alt.Color('party', scale=alt.Scale(domain=list(cmap.keys()), range=list(cmap.values())))
    )

    chart.save('altair-elections.html')

現在與 Matplotlib 方案扯平了,代碼數量達到了 16 行!

下圖是使用我們的樣式調整方案之後的 Altair 效果圖:

![The Altair plot with our custom styling](/data/attachment/album/202008/06/110732gjajux94xnxsuavj.png "The Altair plot with our custom styling.")

結論

儘管在代碼數量上,使用 Altair 繪圖沒有表現出優勢,但它的聲明式繪圖語言使得對圖層的操控更為精密,這是我比較欣賞的。Altair 還提供了清晰而獨立的方式來調校顯示樣式,這使得 相關代碼與繪圖的代碼塊分離開來。Altair 確實是使用 Python 繪圖時又一個很棒的工具庫。

本文首次發佈於 這裡,蒙允編輯後再次發布。

via: https://opensource.com/article/20/6/altair-python

作者:Shaun Taylor-Morgan 選題:lujun9972 譯者:silentdawn-zz 校對: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中國