本篇目的:了解 Matplotlib 的
pcolormesh的細部參數設定,繪製出美觀易讀的圖表
我們在 Day 6 知道了資料如何預處理、以及畫出 wafer mapping 的方式,但大家在繪製圖表時一定會有些自己的設定,例如設定 scale 區間、調整背景顏色、畫出晶粒格線等。好的圖表配置就像加了醬汁的炸鳳尾蝦,完整呈現出圖表製作者的看法。本文會提供繪製 wafer mapping 常用的設定方式,減少大家繪製圖表的時間,並能更專注在資料的解讀上。
我們在 Day 6 中的圖中有繪製出晶粒的格線,但是沒有晶粒的地方也一起繪製出格線,這讓一整張圖顯得非常髒亂。因此我們需要一個物件可以紀錄該位置有無晶粒,並且用該物件設定格線。
在 Day 6 中我們將二維的檢測資料矩陣轉換成 masked_array ,並且masked_array 是一個含有 data 與 mask 的資料集。Mask 就是一個現成的紀錄資料,但是要轉換成一維資料才能作為圖表設定使用,因此我們先將 masked_array 的 mask 取出並拉平:
# 先把mask array的遮罩取出,並拉平成1D
# 有資料的地方是false;沒資料的地方是true
# 拉平後才能放入設定中
flat_mask = wafer_masked.mask.flatten()
拉平後的 1D array 是一個內含 boolean 的 array,我們就可以用這個 array 個別設定有晶粒/ 沒有晶粒的數值。在這裡我們使用 np.where 將有晶粒處的格線設為黑色、而沒有晶粒的地方設成無格線 (對應到none)。
Mask內的
True對應到有檢測資料、False對應到沒有檢測資料
# 以1D array設定框線的顏色
# 有晶粒的地方格線是黑色,沒有晶粒的地方沒有格線
ec_array = np.where(flat_mask, 'none', 'black')
繪圖時,我們只要針對圖面做設定並將上面的設定值傳入 set_edgecolor ,即可依照位置設置格線得到 wafer mapping
# 已設定好 axes, figure, im
# 已設定 colorbar
# 將設定array帶入圖面中
im.set_edgecolor(ec_array)
效果如下圖

透明背景、無坐標軸的 wafer mapping 適合貼到 ppt 報告上,可以減少報告上的無關訊息讓聽者更專注在報告中。要讓圖面只剩下 wafer mapping 的話可以將座標軸、背景關掉,方法如下所示:
# 已設定好 axes, figure, im
ax.set_axis_off() # 不顯示座標軸
fig.set_facecolor('none') # 不設定底色
ax.set_xticks([]) # 移除 X 標記與數字
ax.set_yticks([]) # 移除 Y 標記與數字

Mapping 圖的方向有時會跟我們想看的方向不同,使用以下指令即可翻轉圖面,效果如下圖。可以看到X 軸/ Y 軸的方向與常規不同。
ax.invert_yaxis() # 上下翻轉 y 軸
ax.invert_xaxis() # 左右翻轉 x 軸

Wafer 檢測資料中一定有少數晶粒極為偏離正常值,這些異常晶粒會影響繪圖的 scale,使我們無法區分正常樣品應該有的分布狀態。如上圖所示,大部分的值應在445~455之間,但因為一些特別小值、scale 實際上是 0~ 500,導致整張 mapping 圖都是紅色的、445~ 455 之間的分布完全無法從圖中看出。
這一段會說明如何設定 scale 並提供自己指定與擷取資料 5%~ 95% 資料當 scale 的方法,讓圖表的可讀性更高。
這個方法會手動指定圖表的最大與最小值,並且顯示於圖表的最上/ 最下方,適合有明確想看的資料區間情境 (例如要看多少晶粒是在開 bin 區間內)。
首先我們一樣先建立圖像物件,但下面的 code 中有2處與先前不同的地方
ax.pcolormesh 多傳入 vmin 與 vmax,可以設定著色範圍的最大/ 最小值
fig.colorbar 實例化成 cbar,這是為了後續取出與設定 colorbar 的 tick 使用
# 設定繪圖的最大/最小值
wafer_min = 445
wafer_max = 455
# 省略實例化,與一些繪圖設定
# 建立圖像物件時,加入最大/最小值設定
im = ax.pcolormesh(
x_coords, y_coords, wafer_masked,
cmap='jet', shading='nearest', linewidths=0.5,vmin=wafer_min, vmax= wafer_max
)
# 設定 colorbar
cbar = fig.colorbar(im, ax=ax) # colorbar物件
若參照上面的設定會輸出下圖 (1),可以看到著色範圍確實在 445~ 455 之間。
但我們若希望 colorbar 標示出最大與最小值,要再額外加入以下 code 。在 colorbar 的 tick label 中手動插入 min/ max,並確保我們設定的 min/ max 也是 tick label 的 min/ max 。
# 移除不在wafer_min ~ wafer_max之間的tick,避免白邊異常
ticks = cbar.get_ticks()
valid_ticks = [t for t in ticks if wafer_min <= t <= wafer_max]
# 將最大/ 最小值放入 tick label 中
new_ticks = np.unique(np.concatenate(([wafer_min], valid_ticks, [wafer_max])))
# 將新的 tick label 放入圖表中
cbar.set_ticks(new_ticks)
實作後如下圖 (2),可以看到 tick label 的 min/ max 確實是我們指定的數值。加入最大/ 最小值在圖面上的目的是確保我們放在報告上圖面的 scale 是一致的,這樣子在後續對於不同 wafer 產出的比較與討論才有意義。

這個方法系統會自動抓取檢測 data 的 5 % 與 95 % 對應值,並將其作為著色區間。選用5 % 與 95 % 的原因是避免檢測資料的異常大或小值影響繪圖 (當然,5 % 與 95 %的數值可更動),這種繪圖方式適合首次分析檢測資料,需要確認每一片能力,又或是比較不同 wafer 的產出均勻性使用。
首先我們先計算這片 Wafer 的 5% 與 95% 產出值, 對 masked_array 使用 compressed 即可得只有檢測值的 array (避免空缺值影響後續取值)。另外我另外取區間而不是在 np.percentile 中取 25%、50 %、 75 % 的值是因為產出通常會聚集在特定區間,不可能在我們指定的區間中均勻分布。為了讓 tick label 等距、有較佳視覺效果,因此先取出值後再另外取等距離區間。
# wafer_masked 是 masked_array 形式的檢測資料
# 使用compressed抓出真實晶粒
valid_data = wafer_masked.compressed()
# 抓取5~95 %, 避免極值影響繪圖
extremum = np.percentile(valid_data, [5,95])
# 等距離區間,比較好看
five_numbers = np.linspace(extremum[0], extremum[1], 5).round(0)
後續流程就與上面相同,ax.pcolormesh 傳入 vmin 與 vmax , 接著再用 set_ticks 設定 tick label。實作結果如下。
# 繪圖時指定最大最小值為 5 %/ 95 %
im = ax.pcolormesh(
x_coords, y_coords, wafer_masked,cmap='jet', shading='nearest', linewidths=0.5, vmin=five_numbers[0], vmax=five_numbers[-1])
# 設定colorbar
cbar = fig.colorbar(im, ax=ax) # colorbar物件
cbar.set_ticks(five_numbers) # 設定 tick label

前面所學的 Pandas 與 Matplotlib 都是零散的技巧,接下來要將這些東西串在一起使用了