Python資料展示 - 生成表格圖片

程式設計實驗室發表於2022-04-09

前言

前一篇文章介紹了推送資訊到企業微信群裡,其中一個專案推送的資訊是使用Python自動生成的表格,本文來講講如何用Python生成表格圖片。

選一個合適庫

Python最大的優點就是第三方庫豐富,基本你要什麼功能,都能找到別人實現好的庫,幾行程式碼一呼叫就完事了。

Pytable

專案地址:https://github.com/HiroshiARAKI/pytable

最先找到的是日本人開發的pytab庫,它是基於matplotlib來畫圖的,預設引數下生成的表格外觀一般般,而且顯示不了中文字元,字型也很小,效果不理想。

我一開始還抱著死磕的心態,把這個庫的原始碼下載下來魔改,改了字型和大小,生成的表格終於能看了,但排版還是會出各種奇奇怪怪的問題,比如文字溢位單元格之類的,心累……

Plotly

官網地址:https://plotly.com/

後面找到了一個新的庫:plotly,官網的介紹是:

The front end for ML and data science models

專門為機器學習和資料科學設計的前端展示工具,單純拿來畫表格還算大材小用了~ 它是用網頁來渲染的,看例子效果還可以,我就換成這個plotly試試,嗯,真的可以,那就這個了。

本文會分別介紹這兩個庫的使用,包括我魔改了pytab的地方。

(不過還是推薦plotly,網頁渲染就是好)

pytab

首先安裝

pip install pytab

然後我把畫表格的程式碼封裝成一個函式

import uuid
from typing import List, Dict, Optional, Tuple

import pytab

def draw_table(data: Dict[str, list]):
    """
    畫表格

    :param data: 資料格式 {
        'a': [1.0, 2.1, 3.5, 4.0, 2.0, 1.0, 2.1, 3.5, 4.0, 2.0, ],
        'b': [5.7, 6.1, 7.2, 8.3, 1.2, 5.7, 6.1, 7.2, 8.3, 1.2, ],
        }
    :return:
    """
    # 設定字型,不然顯示不了中文
    pytab.plt.rcParams["font.sans-serif"] = ["SimHei"]
    pytab.table( 
        data=data,
        data_loc='center',
        # th_type='dark',
        th_c='#aaaaee',  # 設定表頭背景顏色
        td_c='gray',  # 設定資料行背景顏色
        table_type='striped',
        figsize=(len(data.keys()), int(len(data.values()) / len(data.keys()) + 1)),
        # fontsize=18,
    )

    # pytab.show()
    temp_file = os.path.join(tempfile.gettempdir(), f'{uuid.uuid4().hex}.jpg')
    print(temp_file)
    pytab.save(temp_file)
    return temp_file

按照註釋的這個資料格式,a和b是表頭列名,後面的陣列是每一列的資料,很好理解

{
    'a': [1.0, 2.1, 3.5, 4.0, 2.0, 1.0, 2.1, 3.5, 4.0, 2.0, ],
    'b': [5.7, 6.1, 7.2, 8.3, 1.2, 5.7, 6.1, 7.2, 8.3, 1.2, ],
}

畫出來的表格是這樣的

再來試試中文顯示會怎麼樣

{
    '列1': [1.0, 2.1, 3.5, 4.0, 2.0, 1.0, 2.1, 3.5, 4.0, 2.0, ],
    '列2': [5.7, 6.1, 7.2, 8.3, 1.2, 5.7, 6.1, 7.2, 8.3, 1.2, ],
}

畫出來是這樣

有點醜吧,勉強能看

OK~ 關於pytab的就不多折騰了,畢竟上限就在這了

接下來看看plotly

plotly

首先安裝

pip install plotly

話不多說,老規矩,我又是寫成一個函式

import uuid
from typing import List, Dict, Optional, Tuple

import plotly.graph_objects as go
import plotly.io as pio

def draw_table(headers: List[str], cells: List[list]):
    """
    畫表

    :param headers: header=dict(values=['A Scores', 'B Scores'])
    :param cells: cells=dict(values=[[100, 90, 80, 90], [95, 85, 75, 95]])
    :return:
    """
    pio.kaleido.scope.default_width = len(','.join(headers)) * 20
    pio.kaleido.scope.default_height = 250 + len(cells[0]) * 20
    fig = go.Figure(data=[go.Table(header=dict(values=headers), cells=dict(values=cells))])
    # fig.show()
    image_file = os.path.join(tempfile.gettempdir(), f'{uuid.uuid4().hex}.jpg')
    print('write image to', image_file)
    fig.write_image(image_file)
    return image_file

這次的引數格式更前面的pytab不一樣,要傳兩個引數,都是陣列型別

第一個是表頭,第二個陣列是單元格

先來個例子試試

draw_table(['列A', '列B'], [[100, 90, 80, 90], [95, 85, 75, 95]])

然後把上面函式程式碼裡的fig.show()註釋去掉,可以看到生成的表格圖片效果

執行後可以發現自動開啟了瀏覽器,因為這個庫是使用網頁來渲染表格的,效果如下

效果比前面那個pytab好一些,哈哈~

OK,就這樣啦。

下次分享一些關於最近用Django開發後臺的。

參考資料

相關文章