iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Claude AI

研究生自救指南:30 天用 Claude Code 打造我的論文工具箱系列 第 17

Day 17|圖表工具:色盲安全色票,印成黑白還是可能失敗

  • 分享至 

  • xImage
  •  

上週做投影片,把 SPSS 的長條圖直接複製貼上去,螢幕上很好看:三種班別用三種顏色分得清清楚楚。前天把口試要交的紙本印出來,系辦影印機只能印黑白。三根柱子變成三種深淺很接近的灰,最左邊跟最右邊幾乎分不出來。

我原本以為這是「印表機的問題」,後來才知道不是。這篇要做的圖表工具,核心不是配色好不好看,是確保同一張圖在螢幕上、彩色列印、黑白影印三種情況下,都還分得出來。中間會有一個我自己也沒想到的結果。

「色盲安全」不等於「黑白安全」
網路上搜得到的「色盲友善色票」,多半是為了色覺辨認障礙的讀者設計的——避開紅綠這種對某些色盲最難分辨的組合。這件事做對了,但它解決的是「色相」的問題,沒有處理「亮度」的問題。

黑白影印機做的事,是把每個顏色換算成一個灰階亮度值,色相全部丟掉。如果兩個顏色色相不同、但亮度剛好接近,色盲安全色票一樣會在黑白影印時變成兩塊很像的灰。這件事色票本身不會告訴你,要自己算。

亮度的算法有公式,人眼對綠色最敏感、對藍色最不敏感,所以不是把 RGB 平均起來,是加權平均:

亮度 = 0.2126×紅 + 0.7152×綠 + 0.0722×藍
這個公式我不用背,讓工具算,但我要知道它在算什麼,不然出來的數字我沒辦法判斷合不合理。

先寫規格檔
跟前面每個工具一樣,analysis/figure-style.md:

圖表規格

通用規則

  • 字型:中文 Microsoft JhengHei,避免顯示成空白方框
  • 輸出解析度:300 dpi(列印用),不用螢幕預設的 100 dpi
  • 圖表不能只靠顏色區分類別,必須同時搭配圖樣(hatch):斜線、交叉線、點狀
  • 色票只能從 Okabe-Ito 色盲安全色票挑,且任兩色的灰階相對亮度差必須 > 0.15
  • 每根柱子上標出樣本數 n
  • 座標軸要有單位,不能只寫變項名稱

核對

  • 輸出圖檔後,另存一份灰階轉換版,肉眼比對一次
  • 用色票本身算出灰階亮度,確認任兩色的差距通過門檻,寫進核對報告

輸出

  • output/<圖名>.png(彩色,300 dpi)
  • output/<圖名>_grayscale_check.png(灰階版,僅供核對,不是要交的檔案)
  • output/figure-check.md(亮度核對報告)
    「任兩色的灰階相對亮度差必須 > 0.15」這條數字是我抓的經驗值,不是哪裡的標準,抓的原則是:0.05 以內幾乎分不出來,0.15 以上大部分情況下看得出深淺差異。這條我還在調,先抓一個保守的門檻。

SKILL.md 全文
存在 .claude/skills/figure-apa/SKILL.md:


name: figure-apa
description: 依 analysis/figure-style.md 的規則畫統計圖表,色盲安全且黑白列印可辨識,輸出彩色圖、灰階核對圖與亮度核對報告。使用者說「畫圖」「做圖表」「統計圖」時使用。

APA 風格統計圖

輸入

清理後的資料檔,使用者指定要畫哪個變項、用什麼圖型

規則

  1. 色票只能用 Okabe-Ito 色盲安全色票裡的顏色,且畫圖前要先算灰階亮度,任兩色差距須 > 0.15,不合格就換色,不得跳過這一步。
  2. 每一類別除了顏色,必須加上不同的 hatch 圖樣。
  3. 中文標籤字型固定用 Microsoft JhengHei,輸出前確認沒有顯示成方框。
  4. 輸出解析度固定 300 dpi。
  5. 畫完之後自動存一份灰階版本,供人眼複查。
  6. 不得在圖表上加入規格檔沒要求的裝飾(陰影、3D 效果、漸層)。

輸出

  • output/<圖名>.png
  • output/<圖名>_grayscale_check.png
  • output/figure-check.md
    我第一次選的色票,被自己的核對機制擋下來
    三個班別要三種顏色,我從 Okabe-Ito 色票裡挑了看起來很標準的組合:橙、天藍、藍綠。跑完核對報告,數字讓我愣了一下:

#E69F00(橙):相對亮度 0.638
#56B4E9(天藍):相對亮度 0.643
#009E73(藍綠):相對亮度 0.476
最小亮度差:0.005(建議 > 0.15)
橙色和天藍色,看起來是完全不同的兩種顏色,換算成灰階之後亮度只差 0.005,幾乎是同一個灰。這兩個顏色都是教科書等級的「色盲安全」推薦色,但沒有人告訴我它們黑白印出來會疊在一起。

換掉天藍,改用藍、紅紫、黃這三色:

#0072B2(藍):相對亮度 0.370
#CC79A7(紅紫):相對亮度 0.557
#F0E442(黃):相對亮度 0.858
最小亮度差:0.187(建議 > 0.15,通過)
這組通過了。重跑一次,圖表存出來,我自己拿灰階版看了一眼:深灰、中灰、淺灰,三根柱子分得很清楚,加上斜線、交叉線、點狀三種圖樣,就算完全看不到顏色也分得出來是哪一組。

實際跑出來的圖
用清理好的資料畫「不同班別的職業倦怠總分」:

班別 n M SD
白班 87 64.85 6.65
小夜班 90 65.83 7.20
大夜班 102 65.72 6.82
彩色版三根柱子是藍色斜線、紅紫色交叉線、黃色點狀,中文標題和座標軸標籤正常顯示,沒有變成方框。灰階版轉出來,深灰、中灰、淺灰配上不同圖樣,肉眼可以清楚分辨。

這裡要老實說一句:這張圖的倦怠總分是我在這支腳本裡自己加總 22 題算出來的,跟 Day 15 說的「加總量表分數還是在 SPSS 裡手動算」是兩條平行線——畫圖用的加總分還沒有拿去跟 SPSS 算出來的版本對過一次。這件事我列進今天的待辦,論文正式的表格和統計,數字要以 SPSS 那邊為準,這裡只是為了畫圖先自己算一份。

哪裡會出錯
中文字型不設定,圖表上的字會變成一格一格的方框。 matplotlib 預設字型不含中文字符,第一次畫圖title 和座標軸的中文全部變成豆腐塊。解法是在畫圖之前指定 Microsoft JhengHei,Windows 內建就有這套字型,不用另外裝。這個坑幾乎每個第一次用 Python 畫中文圖表的人都會踩到一次。

色盲安全色票裡的顏色,兩兩之間不保證灰階夠分得開。 這是今天最大的發現,上面整節都在講。教訓是:色票只解決色相,亮度要自己另外算,不能因為色票的名字裡有「安全」兩個字就放心。

螢幕預覽跟印出來的解析度不一樣。 matplotlib 預設存圖是 100 dpi,螢幕上看起來清楚,印在紙上邊緣會有點糊,字看起來毛毛的。存圖時明確指定 dpi=300,印出來才會跟螢幕上一樣銳利。這個坑不會馬上發現,因為多數人是在螢幕上檢查圖表,直到真正印出來交出去才會看到差別。

只靠顏色,沒有第二種區分依據,還是有風險。 就算亮度差通過門檻,我還是每個類別都配了不同的 hatch 圖樣,這是保險而不是多餘——亮度門檻是我自己抓的經驗值,不是精確的科學保證,兩種區分方式疊在一起,才不會因為一次疏忽就讓圖表在某種輸出情境下失效。

這件事跟資料清理是同一種邏輯
Day 14 說錯誤不會報錯,Day 16 說遺漏值代碼設對了不代表每個下游程式都記得排除它。今天這件事是同一個原則在圖表上的版本:「看起來對」在一種情境下成立,不代表在另一種情境下也成立。 螢幕上看起來完美的配色,黑白影印可能失敗;我自己核對的時候如果只看螢幕,永遠不會發現這個問題。所以規格檔裡才會寫「輸出灰階版本供人眼複查」——這一步不是多做的,是唯一能抓到這種錯誤的方法。

我還不確定的地方
0.15 這個亮度差門檻是我自己抓的,還沒有找到護理或社會科學領域對這件事的具體建議,可能太保守也可能不夠。另外圖表用的加總分還沒跟 SPSS 核對過,這件事我列進下週的待辦,在真正把圖表放進論文之前一定要做。

明天
Day 18:我曾經在原始問卷檔案上直接動手改,三個月後想回頭才發現沒有回頭的選項——那次的完整經過,以及它怎麼變成 Day 4 那條「不要動 data/raw/」的規則。


上一篇
Day 16|表一被退回:不是數字錯,是格式錯,還有一個分母算錯的百分比
下一篇
Day 18|沒有「回頭」這個選項:我在原始資料上直接動手的那三個月
系列文
研究生自救指南:30 天用 Claude Code 打造我的論文工具箱21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言