2022年7月7日 星期四

Python 學習筆記 : Matplotlib 資料視覺化 (四) 表格篇

最近學會 Line Notify 用法之後, 發現它只能傳文字與圖片, 沒辦法傳送 HTML 超文字 (不能像 email 那樣在郵件中傳送網頁表格), 所以如果要傳送表格資料的話, 必須將表格畫成圖檔來傳送. Matplotlib 支援表格繪製, 具體而言就是 pyplot 模組下的 table() 函式, 所以可以將表格資料用 pyplot.table() 繪製成圖片之後再用 Line Notify 推播. 

本系列之前的文章參考 : 



另外有一篇教學文章非常值得參考 :



一. 呼叫 pyplot.table() 繪製表格 : 

從 API 文件可知 pyplot.table() 的參數介面如下 : 

matplotlib.pyplot.table(
    cellText=None, 
    cellColours=None, 
    cellLoc='right'
    colWidths=None, 
    rowLabels=None, 
    rowColours=None, 
    rowLoc='left', 
    colLabels=None, 
    colColours=None, 
    colLoc='center', 
    loc='bottom', 
    bbox=None, 
    edges='closed', 
    **kwargs)

摘要如下表 : 

 pyplot.table() 參數 說明
 colLabels 表格欄標題 (字串串列)
 rowLabels 表格列標題 (字串串列)
 cellText 表格資料, 即資料儲存格內容 (2D 串列)
 loc 表格位置字串 (預設 'bottom', 最好設為 'center', 參考 codes)
 colLoc 列標題文字對齊方式 : 'left', 'center' (預設), 'right' 
 rowLoc 列標題文字對齊方式 : 'left' (預設), 'center', 'right' 
 cellLoc 儲存格內容對齊方式 : 'left', 'center', 'right'  (預設)
 colColours 欄標題儲存格之背景色串列, 可用色彩名 'yellow' 或色碼 '#ffff00'
 rowColours 列標題儲存格之背景色串列, 可用色彩名 'yellow' 或色碼 '#ffff00'
 cellColours 儲存格背景色 (2D 串列), 可用色彩名 'yellow' 或色碼 '#ffff00'
 edges 儲存格邊框樣式 : 'open', 'closed' (預設), 'horizontal','vertical'
 bbox 表格區域 ([x, y, w, h] 串列, x, y 為左下角), 例如 [0.1,0.1, 0.8, 0.8]
 colWidths 欄位寬度串列, 元素為 0~1 之浮點數, 個數須等於欄數

補充說明 :
  • 背景色參數 colColours 與 rowColours 名稱中的色彩是英式拼法的 Colours 而非 Colors, 且色彩串列的結構需匹配 (元素個數必須與列或欄數匹配), 例如三欄可設為 ['yellow', 'yellow', 'yellow'] 或 ['yellow']*3. 資料儲存格背景色參數 cellColours 也是如此 (但它是 2D 串列). 關於色彩名稱參考 : 
    https://matplotlib.org/stable/gallery/color/named_colors.html 
    https://www.webucator.com/article/python-color-constants-module/ 
  • 參數 bbox 用來設定表格繪製區域, 其值為一個 1*4 串列 [x, y, w, h] 其中 x, y 是左下角座標; w 是寬度, h 是高度, 此四者均為 0~1 的浮點數. 有傳入 bbox 參數時 loc 參數將失效. 
  • 參數 colWidths 的值是串列, 元素值同樣也是 0~1 的浮點數, 用來設定各欄的寬度比例, 沒有傳入 colWidths 時欄寬是由各欄均分. 
  • 參數 edges 用來設定儲存格邊框, 預設 'closed' 表示顯示所有邊框; 'open' 表示不顯示邊框; 'horizontal' 表示僅顯示水平邊框; 而 'vertical' 表示僅顯示垂直邊框. 
基本上, 只要傳入欄位標題 colLabels ( tuple 或 list) 與儲存格內容 CellText (2D 的 tuple 或 list) 這兩個參數即可繪製最簡單的表格, 例如 : 


測試 1-1 : 表格繪製初體驗 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
plt.table(cellText=data, colLabels=columns, loc="center")
plt.show()

此例僅傳入欄標題 colLabels 沒有傳入列標題 rowLabel; 另外由於表格預設是置下, 所以此處傳入 loc='center' 將其置中, 結果如下 : 


可見欄標題的儲存格預設是置中對齊; 而資料儲存格則是預設靠右對齊. 可以傳入 cellLoc='left' 與 colLoc='left' 將它們全部靠左對齊, 例如 :


測試 1-2 : 欄標題與資料儲存格內容之對齊設定 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
plt.table(cellText=data, colLabels=columns, loc="center", cellLoc='left',  
          colLoc='left')
plt.show()

結果如下 : 


可見欄標題儲存格與資料儲存格內容均已靠左對齊. 

利用 colColours 參數可以設定欄標題儲存格的背景色, 這樣可以凸顯出最上面那列為欄標題. 其參數值為色碼 (例如 '#ffff00') 或色彩名稱 (例如 'cyan') 字串組成之串列, 但須注意, 其元素個數須與 colLabels 的相同, 例如 : 


測試 1-3 : 用 colColours 設定欄標題儲存格背景色 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
colColours=['yellow', '#ffff00', '#FFFF00']   
plt.table(cellText=data, colLabels=columns, loc="center",
          colColours=colColours)   
plt.show()

此例使用色彩名稱與色碼兩種方式設定欄標題儲存格之背景色, 也可用串列的乘法 :

plt.table(cellText=data, colLabels=columns, loc="center", colColours=['yellow']*3) 或 
plt.table(cellText=data, colLabels=columns, loc="center", colColours=['#ffff00']*3)

這種用法在整列都同色時更簡潔, 但個別儲存格顏色不同時就必須列舉. 

結果如下 :


也可以用 rowLabels 設定列標題, 其值為串列, 元素個數須與資料列數相同, 例如 :


測試 1-4 : 設定列標題儲存格與其背景色 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
colColours=['yellow', '#ffff00', '#FFFF00']   
plt.table(cellText=data, colLabels=columns, loc="center",
          rowLabels=rows, rowColours=['yellow']*5, colColours=['yellow']*3)   
plt.show()

此例新增了一個列標題變數 rows (1~5 的整數), 以及背景色串列 colColours (5 個 'yellow' 串列), 結果如下 :


可見添加列標題後的表格左上角會缺一個儲存格. 

除了欄標題與列標題外, 資料儲存格也可以用 celColours 參數設定背景色, 例如 :


測試 1-5 : 設定資料儲存格背景色 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
colColours=['yellow', '#ffff00', '#FFFF00']    
cellColours=[['white']*3, ['cyan']*3, ['white']*3, ['white']*3, ['white']*3]    
plt.table(cellText=data, colLabels=columns, loc="center",
          rowLabels=rows, rowColours=['yellow']*5, colColours=['yellow']*3,
          cellColours=cellColours)   
plt.show()

注意, cellColours 的尺寸需與表格資料內容串列 data 相同, 此例使用串列乘法將單一元素串列複製為三的元素, 其中第二列資料儲存格背景色都被設為 'cyan', 結果如下 : 




由以上範例可知, 表格的欄寬預設是各欄均分, 但可用 colWidths 參數來設定, 其值為 0~1 浮點數串列 (即佔畫布寬度的比例值), 元素個數須等於欄位個數, 總和應為 1, 例如 : 

測試 1-6 : 設定欄位寬度 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
plt.table(cellText=data, colLabels=columns, loc="center",
          rowLabels=rows, colColours=['yellow']*3,
          colWidths=[0.2, 0.2, 0.6])    
plt.show()

此例用 colWidths 參數將前兩欄寬度設為 20%, 最後一欄舍為 60%, 結果如下 :


參考 :


接下來測試 edges 參數, 預設 'closed' 會顯示所有邊框, 如上面所有範例所示. 若設為 'open' 表示不顯示邊框, 例如 : 


測試 1-7 : 設定表格邊框樣式 (1) : 無邊框 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
colColours=['yellow', '#ffff00', '#FFFF00']    
cellColours=[['white']*3, ['cyan']*3, ['white']*3, ['white']*3, ['white']*3]    
plt.table(cellText=data, colLabels=columns, loc="center",
          rowLabels=rows, rowColours=['yellow']*5, colColours=['yellow']*3,
          cellColours=cellColours, edges='open')  
plt.show()

結果如下 : 


可見若取消邊框, 連儲存格的背景色設定都消失了 (背景色必須要有封閉邊框才能填滿). 

下面是 edges 設為 'horizontal' 的範例 :


測試 1-8 : 設定表格邊框樣式 (2) : 只顯示水平邊框 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
colColours=['yellow', '#ffff00', '#FFFF00']    
cellColours=[['white']*3, ['cyan']*3, ['white']*3, ['white']*3, ['white']*3]    
plt.table(cellText=data, colLabels=columns, loc="center",
          rowLabels=rows, rowColours=['yellow']*5, colColours=['yellow']*3,
          cellColours=cellColours, edges='horizontal')   
plt.show()

結果如下 : 


同樣地, 儲存格背景色設定也失效了. 下面是 edges 設為 'vertical' 的範例 :


測試 1-9 : 設定表格邊框樣式 (3) : 只顯示垂直邊框 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
colColours=['yellow', '#ffff00', '#FFFF00']    
cellColours=[['white']*3, ['cyan']*3, ['white']*3, ['white']*3, ['white']*3]    
plt.table(cellText=data, colLabels=columns, loc="center",
          rowLabels=rows, rowColours=['yellow']*5, colColours=['yellow']*3,
          cellColours=cellColours, edges='vertical')
plt.show()

結果如下 : 


可見填滿儲存格背景色只有在預設 edges='closed' 時才有效果. 

最後來測試 bbox 參數, 它可用來指定表格的箱型位置與尺寸, 即要繪製在畫布的甚麼位置以及大小, 其值為一個串列 [x, y, w, h], 均為 0~1 的浮點數比例值, 其中 x, y 是表格左下角座標位置 (位於畫布長寬多少比例之處); w 是寬度, h 是高度, 例如 : 


測試 1-10 : 設定表格邊框樣式 (3) : 只顯示垂直邊框 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
colColours=['yellow', '#ffff00', '#FFFF00']    
cellColours=[['white']*3, ['cyan']*3, ['white']*3, ['white']*3, ['white']*3]    
plt.table(cellText=data, colLabels=columns, loc="center",
          rowLabels=rows, rowColours=['yellow']*5, colColours=['yellow']*3,
          cellColours=cellColours, bbox=[0.5, 0.5, 0.5,0.5])
plt.show()

此處 bbox 設為 [0.5, 0.5, 0.5, 0.5] 表示表格左下角位於畫布中央, 長與寬都占畫布的 50%, 所以表格會繪製在右上角, 結果如下 : 




如果設為 bbox=[0.5, 0.5, 0.5,0.5], 則表格會繪製於左下角. 


二. Table 物件的屬性與方法 : 

上面範例所繪製的表格樣式均為預設, 但可以呼叫 Table 物件的方法來設定. 首先建立一個簡單表格的 Table 物件 :

>>> import matplotlib.pyplot as plt   
>>> plt.rcParams["font.family"]=["Microsoft JhengHei"]   
>>> columns=["股票名稱", "股票代號", "收盤價"]   
>>> data=[['元大台灣50', '0050', 111.55],   
      ['元大高股息', '0056', 26.81],     
      ['台積電', '2330', 453.5],  
      ['聯電', '2303', 38.05],  
      ['中華電', '2412', 124]]   
>>> table=plt.table(cellText=data, colLabels=columns, loc="center")     
>>> type(table)     
<class 'matplotlib.table.Table'>  

下面利用 eval(), dir(), 以及 type() 來檢視 Table 物件的公開成員 :

>>> members=dir(table)    
>>> for mbr in members:   
    obj=eval('table.' + mbr)   
    if not mbr.startswith('_'):     
        print(mbr, type(obj))    
        
AXESPAD <class 'float'>
FONTSIZE <class 'int'>
add_callback <class 'method'>
add_cell <class 'method'>
matplotlib_table_1.py:1: MatplotlibDeprecationWarning: 
The aname attribute was deprecated in Matplotlib 3.1 and will be removed in 3.3.
  import matplotlib.pyplot as plt
aname <class 'str'>
auto_set_column_width <class 'method'>
auto_set_font_size <class 'method'>
axes <class 'matplotlib.axes._subplots.AxesSubplot'>
clipbox <class 'matplotlib.transforms.TransformedBbox'>
codes <class 'dict'>
contains <class 'method'>
convert_xunits <class 'method'>
convert_yunits <class 'method'>
draw <class 'method'>
edges <class 'str'>
eventson <class 'bool'>
figure <class 'matplotlib.figure.Figure'>
findobj <class 'method'>
format_cursor_data <class 'method'>
get_agg_filter <class 'method'>
get_alpha <class 'method'>
get_animated <class 'method'>
get_celld <class 'method'>
get_children <class 'method'>
get_clip_box <class 'method'>
get_clip_on <class 'method'>
get_clip_path <class 'method'>
get_contains <class 'method'>
get_cursor_data <class 'method'>
get_figure <class 'method'>
get_gid <class 'method'>
get_in_layout <class 'method'>
get_label <class 'method'>
get_path_effects <class 'method'>
get_picker <class 'method'>
get_rasterized <class 'method'>
get_sketch_params <class 'method'>
get_snap <class 'method'>
get_tightbbox <class 'method'>
get_transform <class 'method'>
get_transformed_clip_path_and_affine <class 'method'>
get_url <class 'method'>
get_visible <class 'method'>
get_window_extent <class 'method'>
get_zorder <class 'method'>
have_units <class 'method'>
is_transform_set <class 'method'>
mouseover <class 'bool'>
pchanged <class 'method'>
pick <class 'method'>
pickable <class 'method'>
properties <class 'method'>
remove <class 'method'>
remove_callback <class 'method'>
scale <class 'method'>
set <class 'method'>
set_agg_filter <class 'method'>
set_alpha <class 'method'>
set_animated <class 'method'>
set_clip_box <class 'method'>
set_clip_on <class 'method'>
set_clip_path <class 'method'>
set_contains <class 'method'>
set_figure <class 'method'>
set_fontsize <class 'method'>
set_gid <class 'method'>
set_in_layout <class 'method'>
set_label <class 'method'>
set_path_effects <class 'method'>
set_picker <class 'method'>
set_rasterized <class 'method'>
set_sketch_params <class 'method'>
set_snap <class 'method'>
set_transform <class 'method'>
set_url <class 'method'>
set_visible <class 'method'>
set_zorder <class 'method'>
stale <class 'bool'>
stale_callback <class 'function'>
sticky_edges <class 'matplotlib.artist._XYPair'>
update <class 'method'>
update_from <class 'method'>
zorder <class 'int'>

可見 Table 物件的成員大部分是方法, 說明文件參考 :


常用屬性如下表 : 

 Table 物件常用屬性 說明
 codes 可用的 loc 位置字典
 edges 目前的表格邊框設定

例如 : 

>>> table.codes    # 表格的可用位置字典 (loc 參數設定值)
{'best': 0, 'upper right': 1, 'upper left': 2, 'lower left': 3, 'lower right': 4, 'center left': 5, 'center right': 6, 'lower center': 7, 'upper center': 8, 'center': 9, 'top right': 10, 'top left': 11, 'bottom left': 12, 'bottom right': 13, 'right': 14, 'left': 15, 'top': 16, 'bottom': 17}
>>> table.edges     # 表格框邊設定值
'closed'

Table 物件的常用方法如下表 : 

 Table 物件常用方法 說明
 set_fontsize(x) 設定字型大小為 x (浮點數)
 auto_set_font_size(b) 是否自動設定字型大小 (True/False)
 get_celld() 傳回所有儲存格物件字典
 auto_set_column_width(c) 將指定之欄位 (整數索引) 或多個欄位 (索引串列) 設為自動欄寬
 scale(x, y) 放大表格尺寸, x, y 分別為 X, Y 軸放大倍數


1. 設定字型大小 : 

建立 Table 物件時會自動指定字型大小 (預設 10), 這可以呼叫其 set_fontsize() 方法更改, 但更改之前最好先呼叫 auto_set_font_size(False) 關閉自動模式, 例如 : 


測試 2-1 : 設定字型大小 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center")
table.auto_set_font_size(False)    # 關閉自動模式  
table.set_fontsize(14)                    # 設定字型大小
plt.show()

結果如下 : 


可見字型設定會套用到所有儲存格 (包含標題).

參考 :



2. 儲存格物件 : 

如果要控制儲存格的樣式必須取得儲存格物件, 這可以透過呼叫 Table 物件的 get_celld() 方法來取得一個包裹著所有儲存格的字典物件, 以上面的簡單表格為例 :

>>> import matplotlib.pyplot as plt   
>>> plt.rcParams["font.family"]=["Microsoft JhengHei"]   
>>> columns=["股票名稱", "股票代號", "收盤價"]   
>>> data=[['元大台灣50', '0050', 111.55],   
      ['元大高股息', '0056', 26.81],     
      ['台積電', '2330', 453.5],  
      ['聯電', '2303', 38.05],  
      ['中華電', '2412', 124]]   
>>> table=plt.table(cellText=data, colLabels=columns, loc="center") 
>>> cellDict=table.get_celld()
>>> type(cellDict)      
<class 'dict'>      

此字典是以儲存格座標索引的 tuple 為鍵 : 

>>> cellDict.keys()  
dict_keys([(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2), (5, 0), (5, 1), (5, 2), (0, 0), (0, 1), (0, 2)])

可用此 tuple 鍵來取得其值 :

>>> cell=cellDict[(1, 0)]    
>>> type(cell)    
<class 'matplotlib.table.CustomCell'>     

可見這儲存格是被包裹成一個 CustomCell 物件. 接著可用 eval(), dir(), 以及 type() 來檢視 Table 物件的公開成員 :

>>> membsers=dir(cell)    
>>> for mbr in members:       
    obj=eval('cell.' + mbr)      
    if not mbr.startswith('_'):           
        print(mbr, type(obj))      
        
PAD <class 'float'>
add_callback <class 'method'>
matplotlib_table_2_1.py:1: MatplotlibDeprecationWarning: 
The aname attribute was deprecated in Matplotlib 3.1 and will be removed in 3.3.
  import matplotlib.pyplot as plt
aname <class 'str'>
angle <class 'float'>
auto_set_font_size <class 'method'>
axes <class 'NoneType'>
clipbox <class 'NoneType'>
contains <class 'method'>
contains_point <class 'method'>
contains_points <class 'method'>
convert_xunits <class 'method'>
convert_yunits <class 'method'>
draw <class 'method'>
eventson <class 'bool'>
figure <class 'matplotlib.figure.Figure'>
fill <class 'bool'>
findobj <class 'method'>
format_cursor_data <class 'method'>
get_aa <class 'method'>
get_agg_filter <class 'method'>
get_alpha <class 'method'>
get_animated <class 'method'>
get_antialiased <class 'method'>
get_bbox <class 'method'>
get_capstyle <class 'method'>
get_children <class 'method'>
get_clip_box <class 'method'>
get_clip_on <class 'method'>
get_clip_path <class 'method'>
get_contains <class 'method'>
get_cursor_data <class 'method'>
get_data_transform <class 'method'>
get_ec <class 'method'>
get_edgecolor <class 'method'>
get_extents <class 'method'>
get_facecolor <class 'method'>
get_fc <class 'method'>
get_figure <class 'method'>
get_fill <class 'method'>
get_fontsize <class 'method'>
get_gid <class 'method'>
get_hatch <class 'method'>
get_height <class 'method'>
get_in_layout <class 'method'>
get_joinstyle <class 'method'>
get_label <class 'method'>
get_linestyle <class 'method'>
get_linewidth <class 'method'>
get_ls <class 'method'>
get_lw <class 'method'>
get_patch_transform <class 'method'>
get_path <class 'method'>
get_path_effects <class 'method'>
get_picker <class 'method'>
get_rasterized <class 'method'>
get_required_width <class 'method'>
get_sketch_params <class 'method'>
get_snap <class 'method'>
get_text <class 'method'>
get_text_bounds <class 'method'>
get_tightbbox <class 'method'>
get_transform <class 'method'>
get_transformed_clip_path_and_affine <class 'method'>
get_url <class 'method'>
get_verts <class 'method'>
get_visible <class 'method'>
get_width <class 'method'>
get_window_extent <class 'method'>
get_x <class 'method'>
get_xy <class 'method'>
get_y <class 'method'>
get_zorder <class 'method'>
have_units <class 'method'>
is_transform_set <class 'method'>
mouseover <class 'bool'>
pchanged <class 'method'>
pick <class 'method'>
pickable <class 'method'>
properties <class 'method'>
remove <class 'method'>
remove_callback <class 'method'>
set <class 'method'>
set_aa <class 'method'>
set_agg_filter <class 'method'>
set_alpha <class 'method'>
set_animated <class 'method'>
set_antialiased <class 'method'>
set_bounds <class 'method'>
set_capstyle <class 'method'>
set_clip_box <class 'method'>
set_clip_on <class 'method'>
set_clip_path <class 'method'>
set_color <class 'method'>
set_contains <class 'method'>
set_ec <class 'method'>
set_edgecolor <class 'method'>
set_facecolor <class 'method'>
set_fc <class 'method'>
set_figure <class 'method'>
set_fill <class 'method'>
set_fontsize <class 'method'>
set_gid <class 'method'>
set_hatch <class 'method'>
set_height <class 'method'>
set_in_layout <class 'method'>
set_joinstyle <class 'method'>
set_label <class 'method'>
set_linestyle <class 'method'>
set_linewidth <class 'method'>
set_ls <class 'method'>
set_lw <class 'method'>
set_path_effects <class 'method'>
set_picker <class 'method'>
set_rasterized <class 'method'>
set_sketch_params <class 'method'>
set_snap <class 'method'>
set_text_props <class 'method'>
set_transform <class 'method'>
set_url <class 'method'>
set_visible <class 'method'>
set_width <class 'method'>
set_x <class 'method'>
set_xy <class 'method'>
set_y <class 'method'>
set_zorder <class 'method'>
stale <class 'bool'>
stale_callback <class 'NoneType'>
sticky_edges <class 'matplotlib.artist._XYPair'>
update <class 'method'>
update_from <class 'method'>
validCap <class 'tuple'>
validJoin <class 'tuple'>
visible_edges <class 'str'>
xy <class 'tuple'>
zorder <class 'int'>

可見 CustomCell 物件有許多成員是繼承自 Table 物件. 

CustomCell 物件的常用方法如下表 : 

 CustomCell 物件方法 說明
 set_fontsize(x) 設定字型大小為 x (浮點數)
 set_linewidth(w) 設定儲存格框線寬度 w (浮點數)
 set_linestyle(s) 設定儲存格框線樣式 s (字串), 例如 'solid' (預設), 'dashed', 'dotted'
 set_color(c) 設定儲存格背景色與框邊顏色 , 可用色彩名 'yellow' 或色碼 '#ffff00'
 set_facecolor(c) 設定儲存格背景色, 可用色彩名 'yellow' 或色碼 '#ffff00'
 set_edgecolor(c) 設定儲存格邊框顏色 c, 可用色彩名 'yellow' 或色碼 '#ffff00'
 set_height(h) 設定儲存格高度 h (浮點數, 預設 0.045)

這些 setter 方法都有其對應的 getter 方法, 例如 : 

>>> cell.get_fontsize()    
10.0  
>>> cell.get_height()   
0.0450937950937951

可見預設的字型大小為 10, 儲存格高度預設約為 0.045. 

以下分別測試這些方法的應用. 


3. 設定儲存格框線之粗細與顏色 : 

Table 物件預設之表格框邊粗細為 1, 感覺有點粗, 如果要用細框邊可利用 CustomCell 物件的 set_linewidth() 方法將其設為 0.5, 例如 : 


測試 3-1 : 設定儲存格框線粗細 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center")
for key, cell in table.get_celld().items():   
    cell.set_linewidth(0.5)       
plt.show()

此處用迴圈走訪每一個儲存格物件, 然後呼叫 set_linewidth(0.5) 將框線縮小一半, 結果如下 :


可見表格已經變成清爽的細框線了. 

參考 :


設定儲存格框線顏色必須呼叫儲存格物件的 set_edgecolor() 方法, 例如 : 


測試 3-2 : 設定儲存格框線顏色 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center")
for key, cell in table.get_celld().items():
    cell.set_edgecolor('blue')      # 也可傳入 '#0000FF' 或 '#0000ff'
plt.show()

此例呼叫 set_edgecolor() 傳入藍色名稱, 結果如下 :


可見整個表格邊框都改成藍色了.  參考 :


儲存格框線樣式預設是實線 ('solid'), 可用儲存格物件的 set_linestyle() 設定, 可用樣式參考 :


例如 :


測試 3-3 : 設定儲存格框線樣式 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center")
for key, cell in table.get_celld().items():
    cell.set_linestyle('dotted')    
plt.show()

此例用 set_linestyle() 將儲存格框線設為點狀虛線 ('dotted'), 結果如下 :


可見整個表格框線都變成虛線了. 


4. 設定儲存格高度 : 

儲存格高度可用 CustomCell 物件的 set_height() 方法來設定, 參考 : 


表格預設高度為 0.045, 視覺印象較窄, 下面範例將其設為兩倍的 0.09 :


測試 4-1 : 設定儲存格高度 [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center")
for key, cell in table.get_celld().items():       
    cell.set_height(0.09)   
plt.show()

結果如下 : 


可見儲存格高度變大了. 


5. 設定儲存格背景色 : 

雖然在建立表格時可用 cellColours 參數來設定儲存格背景色, 但那是在資料儲存格尺寸已知且固定情況下的作法; 如果資料是動態的, 則需使用儲存格物件的 set_facecolor() 方法來做, 當然靜態且固定的資料也可以用, 例如 : 


測試 5-1 : 利用 set_facecolor() 設定儲存格背景色(1) [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center",
                colColours=['yellow']*3)
for key, cell in table.get_celld().items():
    cell.set_facecolor('cyan')   
plt.show()

此例在建立 Table 物件時先用 colColours 參數將欄標題背景色設定成黃色, 然後在走訪儲存格物件的迴圈中呼叫 set_facecolor() 將其背景色設為 'cyan' 色, 結果如下 :


可見預先用 colColours 設定的欄標題儲存格背景色都被 set_facecolor() 蓋掉了. 解決此問題的辦法是判斷目前儲存格是否位於第一列 (欄標題), 是的話才呼叫 set_facecolor(), 這可以從 items() 傳回的 key 來判斷, 此 key 是一個表示儲存格座標索引的 tuple, 例如 (1, 2) 表示此為第二列第三欄的儲存格, 而欄標題位於第一列, 其 key 為 (0, x), 所以 key[0] 若為 0 表示第一列儲存格, 也就是欄標題儲存格, 就不呼叫 set_facecolor(), 作法如下 : 


測試 5-2 : 利用 set_facecolor() 設定儲存格背景色(2) [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center",
                colColours=['yellow']*3)
for key, cell in table.get_celld().items():    
    if key[0] != 0:                        # 不是第一列 (欄標題儲存格)
        cell.set_facecolor('cyan')     
plt.show()

結果如下 : 


這樣就可以保留欄標題的背景色了. 但這樣的做法在有列標題時還需要修改, 例如 : 


測試 5-3 : 利用 set_facecolor() 設定儲存格背景色(3) [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)   
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center",
                rowLabels=rows, rowColours=['yellow']*5,   
                colColours=['yellow']*3)   
for key, cell in table.get_celld().items():
    if key[0] != 0:
        cell.set_facecolor('cyan')
plt.show()

結果如下 : 


可見列標題也被 set_facecolor() 覆蓋掉了, 解決辦法是還要增加列索引的判斷, 在迭代 table.get_celld().items() 時傳回的 key 是代表列與欄座標索引的 tuple (列, 欄), 從上例已知 key[0] 是列索引, 而 key[1] 是欄索引, 都是 0 起始, 故 key[0]==0 為第一列, key[1]==0 為第一欄, 而列標題為 key[1]==-1, 這可以從檢視 key 內容看出來 : 

>>> columns=["股票名稱", "股票代號", "收盤價"]   
>>> rows=range(1, 6)   
>>> data=[['元大台灣50', '0050', 111.55],   
      ['元大高股息', '0056', 26.81],     
      ['台積電', '2330', 453.5],  
      ['聯電', '2303', 38.05],  
      ['中華電', '2412', 124]]   
>>> table=plt.table(cellText=data, colLabels=columns, loc="center",   
                rowLabels=rows, rowColours=['yellow']*5,   
                colColours=['yellow']*3)   
>>> for key, cell in table.get_celld().items():    
    print(key)   
    
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)
(3, 0)
(3, 1)
(3, 2)
(4, 0)
(4, 1)
(4, 2)
(5, 0)
(5, 1)
(5, 2)
(0, 0)
(0, 1)
(0, 2)
(1, -1)   
(2, -1)
(3, -1)
(4, -1)
(5, -1)

所以只要排除 key[0]==0 and key[1]==-1 即可避免欄標題與列標題背景色被 set_facecolor() 覆蓋, 讓 set_facecolor() 只套用在資料儲存格, 例如 :


測試 5-4 : 利用 set_facecolor() 設定儲存格背景色(4) [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center",
                rowLabels=rows, rowColours=['yellow']*5,
                colColours=['yellow']*3)
for key, cell in table.get_celld().items():
    if key[0] != 0 and key[1] != -1:        # 除欄標題與與列標題之儲存格外
        cell.set_facecolor('cyan')   
plt.show()

結果如下 : 


可見只有資料儲存格才會套用 'cyan' 背景色, 欄標題與列標題儲存格不受影響. 如果要讓資料儲存格隔列交替更換背景色, 從上面檢視 key 內容可知, 用迴圈走訪 CustomCell 物件時是逐欄再逐列的, 所以只要在呼叫 set_facecolor() 之前用列索引 key[0] 來判斷是否已換列即可, 最簡單的作法就是根據列索引是奇數還是偶數, 這可以用 % 運算子輕易達成, 例如 : 


測試 5-5 : 利用 set_facecolor() 設定儲存格背景色(5) [看原始碼]

import matplotlib.pyplot as plt

plt.rcParams["font.family"]=["Microsoft JhengHei"] 
columns=["股票名稱", "股票代號", "收盤價"]
rows=range(1, 6)
data=[['元大台灣50', '0050', 111.55],
      ['元大高股息', '0056', 26.81],
      ['台積電', '2330', 453.5],
      ['聯電', '2303', 38.05],
      ['中華電', '2412', 124]]
plt.axis('off')
table=plt.table(cellText=data, colLabels=columns, loc="center",
                rowLabels=rows, rowColours=['yellow']*5,
                colColours=['yellow']*3)
for key, cell in table.get_celld().items():
    if key[0] != 0 and key[1] != -1 :
        if key[0]%2 == 0:                  # 判斷是否為偶數列
            cell.set_facecolor('cyan')
        else:
            cell.set_facecolor('white') 
plt.show()

結果如下 : 


這種背景色交替的表格在資料很長時有助於閱讀. 

參考 : 


沒有留言 :