R 學習筆記:R 色彩
色彩理論
色彩本身所含有很多信息, 對色彩的研究可以稱為色彩學. 對於繪圖選擇顏色, 不需要掌握色彩學的知識, 但也應該了解基本的色彩和色彩空間 (color space) 的知識.
色彩空間 (color space) 是計算機上顏色的組成形式. 常見的如 RGB, HSV, HCL 等. 不同的色彩空間可以相互轉換.
RGB
RGB (Red Green Blue) 的色彩空間參考了人眼所能察覺的自然光的搭配方式, 紅綠藍做為三基色, 可以按照一定的比例搭配出來各種色彩, 其色彩空間是以紅綠藍三個顏色的比例作為坐標軸的坐標系. 紅藍綠的一樣的情況下產生白光, 全都沒有的情況下是黑色, 而剩下的情況則根據顏色的比例不同顯示不同的光. 這樣的顏色顯示方式也是三基色顯示屏顯示顏色的原理. 計算機裡面對每一個三基色定義了256個等級, 所以我們可以看到 (255, 255, 255) 代表白色, (0, 0, 0) 代表黑色, (255, 0, 0) 代表正紅色等. 這是用十進位來表示, 如果採用十六進位表示則是 #000000 代表黑色, #FFFFFF 代表白色. 因為 255(10) == FF(16).
HSV
HSV (Hue Saturation Value/Brighness, 色調 飽和度 亮度) 的色彩空間實際上是對 RGB
的色彩空間做了坐標變換, HSV 是一個圓柱坐標系, H 為角度, S 為半徑, V 為高度. 對於 HSV (假設 S 最大為 1, V 最大為 1), 純色的飽和度為 1, 亮度為 1. HSV 色彩空間更符合我們人對顏色的直覺認知. 使用 HSV 色彩空間, 我們就會趨向於使用飽和度較高的色彩.HSL
HSL (Hue Saturation Luminance/Lightness, 色調 飽和度 明度) 的色彩空間和 HSV 很像,
也是對 RGB 色彩空間的坐標變換, 是一個圓柱坐標系, H 為角度, S 為半徑, L 為高度. 而在 HSL 中, 飽和度的定義和 HSV 的飽和度的定義不太一樣, 同時明度和亮度的定義也不同. 對於我們通常認為的純色, 就是紅色等, 其飽和度在兩種色彩空間中都是 1, 但是對於 HSL, 其明度為 1/2, 而在 HSV 中其亮度為 1. 因為 HSL 中的飽和度和我們所認為的顏色的飽和度不太一樣, 所以也被稱為色品 (chroma) 來和 HSV 中的飽和度進行區分.坐標轉換
RGB 和 HSV, HSL 坐標系可以進行坐標轉換. 即把直角坐標系轉換為相應的圓柱坐標系.
CMYK
CMYK 代表青色 (cyan), 品紅 (magenta), 黃色 (yellow) 和黑色 (key, black). CMYK 和
RGB 靠顏色相加搭配顏色不同, CMYK 採用的是相減的辦法, CMY 三種顏色配合起來是黑色, 而減少其中一種或幾種顏色的量就會產生其他顏色, 如果一種顏色也沒有則是白色. CMYK 是印刷業中採用的方法, 為了節約成本和取得更好的印刷效果, 直接搭配黑色, 而不使用三種顏色來組合為黑色.R 中的色彩與調色板包和函數
在繪製統計圖的時候, 選擇合適的顏色會對最後的呈現效果產生巨大的影響. 對於選擇顏色, 有很多需要注意的細節, 自己一個個顏色去調選,
畢竟是費時費力, 而結果又不見得好的事情. R 中定義了很多顏色, 同時, R 中也有很多幫助調選顏色和調色板的顏色,
可以方便地獲得所需要的顏色或者調色板.grDevices
grDevices 是 R core 維護的包, 提供了對於 R 基本繪圖的設備色彩和字體的支持, 其中有一些方便操作色彩的函數.
colors 函數可以返回一個在 R 中已經定義名稱的色彩的向量, 共有 657 個色彩. R 使用十六進位的數字去表示顏色, 例如 "#FF0000" 代表 "red" 和 rgb(1,0,0).
rgb 函數, hsv 函數和 hcl 函數分別採用 RGB HSV 和 CIELUV 的色彩空間去定義顏色,這三個函數會返回十六進位的代表顏色的代碼. rgb 函數和 hsv 函數的三個維度的取值範圍均是 0 到 1, 而 hcl 函數的參數相對複雜, h 的取值範圍在 0 到 360, 其中 0 為 red, l 的取值在 0 到 100, c 的取值依賴於 h 和 l.
rgb(1,0,0)n#[1] "#FF0000"nhsv(0,1,1)n#[1] "#FF0000"nhcl(h = 0, l = 50, c = 500)n[1] "#FF0000"n
如果知道 R 中定義的顏色的名稱或者, 可以使用 col2rgb 把名稱或者十六進位代碼轉換為 RGB 色彩. 也可以使用 rgb2hsv 把 RGB 轉換為 HSV 色彩空間. 另外 convertColor 是更為通用的轉換色彩空間的函數, 支持 colorspaces 對象中所列出的色彩空間.
col2rgb("red")n# [,1]n#red 255n#green 0n#blue 0ncol2rgb("#FF0000")n# [,1]n#red 255n#green 0n#blue 0nrgb2hsv(r = 255, g = 0, b = 0)n# [,1]n#h 0n#s 1n#v 1nrgb2hsv(col2rgb("#FF0000"))n# [,1]n#h 0n#s 1n#v 1n
在 grDevices 中有一些定義好的函數可以方便地輸出特定類型的顏色序列.
- rainbow: 輸出各種彩虹色.
- heat.colors: 輸出熱圖色, 為紅色經過黃色到白色的漸變色.
- terrain.colors: 輸出地形圖中會出現的顏色, 為綠色經過黃褐色到白色的漸變色.
- topo.colors: 輸出藍色經過綠色到黃褐色的漸變色.
- cm.colors: 輸出從青色經過白色到品紅的漸變色.
- gray: 或者 grey. 輸出一系列的灰色, 參數 level 代表亮度, 0 為 black, 1 為 white.
- gray.colors: 或者 grey.colors. 輸出一個灰色向量.
方便使用的色彩生成函數限制了其使用地靈活性, 如果上面的函數不能滿足需求, 還可以使用 colorRamp 和 colorRampPalette 函數. 這兩個函數會接受一個色彩向量作為輸入, 指定顏色變換的節點, 其返回值均是一個函數, 該返回的函數可以根據需要返回計算出的位於指定的顏色節點之間的過渡顏色. 區別在於, colorRamp 的返回函數接受的輸入值為 0 到 1 的數字, 返回相對應的 RGB 顏色, 而 colorRampPalette 則接受一個整數, 返回相應數量的顏色作為調色板.
myReds <- colorRamp(c("red", "white"))nmyReds(c(0, 0.5, 1)) n# [,1] [,2] [,3] #[1,] 255 0.0 0.0 n#[2,] 255 127.5 127.5 #[3,] 255 255.0 255.0nmyBlues <- colorRampPalette(c("blue", "white")) nmyBlues(5) n#[1] "#0000FF" "#3F3FFF" "#7F7FFF" "#BFBFFF" "#FFFFFF"n
densCols 函數是可以根據你所提供的數量按照數量分布的密度來生成不同深度顏色的顏色序列, 在畫散點圖的時候, 如果需要把點的顏色按照密度多少進行調整, 則可以使用該函數.
rd <- data.frame(n x=rnorm(100),n y=rnorm(100)n)nrcol <- densCols(n rd,n colramp=colorRampPalette(n c(#ff0000, #000000) # 紅色到黑色n )n)nplot(rd, pch=20, col=rcol)n
RColorBrewer
ColorBrewer 網站本來是一個用於地理信息系統配色的網站, 不過因為其色彩搭配十分出眾, 也用於地圖之外的很多地方, R 中有 RColorBrower 包整合了相應的調色板, 另外著名的 ggplot2 也整合了這些調色板.
RColorBrewer 包中設置好的固定的調色板是來自於 colorbrewer 網站的. 可以使用RColorBrewer::display.brewer.all() 函數來繪製出該包中設置好的調色板. 而在 brewer.pal.info 變數中保存了這些調色板的信息, 包括名稱, 顏色數量類型和是否是色盲友好型.
http://brewer.pal.info 的結果如下:
PALETTE MAXCOLORS CATEGORY COLORBLINDnBrBG 11 div TRUEnPiYG 11 div TRUEnPRGn 11 div TRUEnPuOr 11 div TRUEnRdBu 11 div TRUEnRdGy 11 div FALSEnRdYlBu 11 div TRUEnRdYlGn 11 div FALSEnSpectral 11 div FALSEnAccent 8 qual FALSEnDark2 8 qual TRUEnPaired 12 qual TRUEnPastel1 9 qual FALSEnPastel2 8 qual FALSEnSet1 9 qual FALSEnSet2 8 qual TRUEnSet3 12 qual FALSEnBlues 9 seq TRUEnBuGn 9 seq TRUEnBuPu 9 seq TRUEnGnBu 9 seq TRUEnGreens 9 seq TRUEnGreys 9 seq TRUEnOranges 9 seq TRUEnOrRd 9 seq TRUEnPuBu 9 seq TRUEnPuBuGn 9 seq TRUEnPuRd 9 seq TRUEnPurples 9 seq TRUEnRdPu 9 seq TRUEnReds 9 seq TRUEnYlGn 9 seq TRUEnYlGnBu 9 seq TRUEnYlOrBr 9 seq TRUEnYlOrRd 9 seq TRUEn
brewer.pal 函數可以用來返回所需要的若干數量的顏色. 因為 RColorBrewer 定義好了許多不同類型的調色板, 通過
brewer.pal 函數得到的顏色往往搭配很好. 使用 display.brewer.pal 函數可以用圖像顯示出所選擇的顏色. 每個調色板有顏色數量的限制, 所選擇的顏色數量應該在 3 到最大值之間.colorspace
colorspace 包專註於不同的色彩空間的顏色選擇和相互轉換. colorspace 包中有 RGB, sRGB, HSV, HLS, XYZ, LUV, LAB 等多種色彩空間的創建函數可以用來創建色彩對象, 其返回值是一個 S4 的對象. 同時也有 hex 函數來把 S4 色彩對象轉換為 R 中的十六進位色彩代碼. hex2RGB 則可以把十六進位色彩代碼轉換為 RGB 對象.
對於不同的色彩空間的對象, 可以通過 as 函數來轉換. 可以使用 coords 函數獲得色彩對象在對應色彩空間的具體的值.
myred.rgb <- RGB(1, 0, 0)n(myred.hls <- as(myred.rgb, "HLS"))n# H L S n#[1,] 0 0.5 1 nisS4(myred.hls) n#[1] TRUE n(myred.hls.coord <- coords(myred.hls)) n# H L S n#[1,] 0 0.5 1 nclass(myred.hls.coord) n#[1] "matrix"n
mixcolor 函數可以計算兩個顏色調配出的顏色. desaturate 函數可以在 HCL 色彩空間內把輸入的顏色 (十六位進位代碼) 轉換為相應亮度的灰度.
mixcolor(n alpha = 0.5,n color1 = hex2RGB("#FF0000"),n color2 = hex2RGB("#0000FF")n)n# R G Bn#[1,] 0.5 0 0.5ndesaturate("#FF0000")n#[1] "#7F7F7F"n
choose_palette 函數提供了一個圖形化的選擇調色板的界面, 可以直觀地選擇顏色和設置調色板.
總結
- 計算機中顏色可以有多種表示方式:
- RGB, 最常用到的顏色表示方法, 由紅綠藍三原色去組合顏色.
- HSV, 色調 飽和度 亮度
- HSL, 色調 飽和度 明度
- 一些常用色彩函數
- rainbow: 輸出各種彩虹色.
- heat.colors: 輸出熱圖色, 為紅色經過黃色到白色的漸變色.
- terrain.colors: 輸出地形圖中會出現的顏色, 為綠色經過黃褐色到白色的漸變色.
- topo.colors: 輸出藍色經過綠色到黃褐色的漸變色.
- cm.colors: 輸出從青色經過白色到品紅的漸變色.
- gray: 或者 grey. 輸出一系列的灰色, 參數 level 代表亮度, 0 為 black, 1 為 white.
- gray.colors: 或者 grey.colors. 輸出一個灰色向量.
- 色彩轉換函數: col2rgb, col2rgb, rgb2hsv, rgb2hsv
- colorRamp 和 colorRampPalette 函數 動態生成顏色序列
- densCols 按照密度生成顏色序列
- RColorBrewer 包提供 ColorBrewer 調色板
- colorspace 包提供更多色彩空間轉換函數
Reference
- Wikipedia: RGB
- Wikipedia: HSL and HSV
- PDF: Escaping RGBland: Selecting Colors for Statistical Graphics
- PDF: CRAN-colorspace vignettes
推薦閱讀: