数据可视化不可避免的就是要选择一些颜色方案,颜色方案除了手动设置之外,在R中也有自动生成颜色方案的工具。
R中的HCL配色方案
HCL本意是和RGB HSV等一样的颜色空间的术语,由于这里所用的颜色方案在R中是hcl.pals函数,所以就称为HCL配色方案了。 HCL相比较HSV等颜色空间的一个重要优点就是颜色的视觉明度是均一的,在R中也是推荐使用hcl颜色方案,不推荐使用rainbow等颜色方案了。 有关于HCL的有点,可以参看https://jessieji.com/2020/hcl-instead-of-hsl。
hcl.pals可以查看内置的hcl颜色方案:
代码语言:javascript复制hcl.pals("qualitative")
# [1] "Pastel 1" "Dark 2" "Dark 3" "Set 2" "Set 3" "Warm" "Cold" "Harmonic" "Dynamic"
hcl.pals("sequential")
# [1] "Grays" "Light Grays" "Blues 2" "Blues 3" "Purples 2" "Purples 3" "Reds 2" "Reds 3" "Greens 2"
# [10] "Greens 3" "Oslo" "Purple-Blue" "Red-Purple" "Red-Blue" "Purple-Orange" "Purple-Yellow" "Blue-Yellow" "Green-Yellow"
# [19] "Red-Yellow" "Heat" "Heat 2" "Terrain" "Terrain 2" "Viridis" "Plasma" "Inferno" "Rocket"
# [28] "Mako" "Dark Mint" "Mint" "BluGrn" "Teal" "TealGrn" "Emrld" "BluYl" "ag_GrnYl"
# [37] "Peach" "PinkYl" "Burg" "BurgYl" "RedOr" "OrYel" "Purp" "PurpOr" "Sunset"
# [46] "Magenta" "SunsetDark" "ag_Sunset" "BrwnYl" "YlOrRd" "YlOrBr" "OrRd" "Oranges" "YlGn"
# [55] "YlGnBu" "Reds" "RdPu" "PuRd" "Purples" "PuBuGn" "PuBu" "Greens" "BuGn"
# [64] "GnBu" "BuPu" "Blues" "Lajolla" "Turku" "Hawaii" "Batlow"
hcl.pals("diverging")
# [1] "Blue-Red" "Blue-Red 2" "Blue-Red 3" "Red-Green" "Purple-Green" "Purple-Brown" "Green-Brown" "Blue-Yellow 2" "Blue-Yellow 3"
# [10] "Green-Orange" "Cyan-Magenta" "Tropic" "Broc" "Cork" "Vik" "Berlin" "Lisbon" "Tofino"
hcl.pals("divergingx")
# [1] "ArmyRose" "Earth" "Fall" "Geyser" "TealRose" "Temps" "PuOr" "RdBu" "RdGy" "PiYG" "PRGn" "BrBG" "RdYlBu"
# [14] "RdYlGn" "Spectral" "Zissou 1" "Cividis" "Roma"
可以发现颜色方案分为四类:qualitative、 sequential、 diverging、 divergingx,分别取二个相应的Palettes看一下颜色的效果如何。
代码语言:javascript复制# 定义一个函数用于查看颜色的效果
showColors <- function(x, ...){
barplot(rep(1, length(x)), col = x, axes = FALSE, ...)
}
选取hcl颜色方案是使用hcl.colors函数,比如从Pastel 1颜色方案中取10个颜色:
代码语言:javascript复制hcl.colors(10, palette = "Pastel 1")
# [1] "#FFC5D0" "#F6CBB7" "#E2D4A8" "#C5DCAB" "#A8E1BF" "#99E2D8" "#A4DDEF" "#C4D5FB" "#E4CBF9" "#F9C5E9"
showColors(hcl.colors(10, palette = "Pastel 1"), main = "Pastel 1")
四大配色方案中各随机选二个方案,查看效果:
代码语言:javascript复制# 布局4行2列
opar <- par(no.readonly = TRUE)
par(mfrow = c(4, 2), mar = c(1,1,3,1))
for(panel in c('qualitative', 'sequential', 'diverging', 'divergingx')){
pal <- sample(hcl.pals(panel), 2)
for(p in pal){
col_in_pal <- hcl.colors(10, p)
showColors(col_in_pal, main = paste0(panel, ": ", p))
}
}
# 复原布局
par(opar)
可以看到:
- qualitative颜色方案的颜色有多种色调,常用于着色离散变量;
- sequential的颜色方案中色调较少,体现了颜色的连续过渡,可以用于着色连续变量;
- diverging和divergingx也是颜色的连续过渡,但是不同于sequential,它的颜色在深浅上存在一个中心点,中心点两侧颜色逐步加深过渡,这样的颜色方案适合有中心点的连续变量,比如相关性数据:数据范围是-1到1,0是中心点,于是两端的颜色需要两个深色,而中心点可以使用最浅的颜色。
RColorBrewer
RColorBrewer包的配色方案通过display.brewer.all查看,可以发现它的颜色方案也是类似的:sequential、qualitative和diverging。
代码语言:javascript复制RColorBrewer::display.brewer.all()
如果需要获取具体的颜色,可以使用brewer.pal函数:
代码语言:javascript复制RColorBrewer::brewer.pal(3, "Dark2")
# [1] "#1B9E77" "#D95F02" "#7570B3"
不同于hcl的配色方案,RColorBrewer中颜色方案数量是固定的,不会对颜色进行自动插值,比如Dark2配色一共只有8个颜色,超过8个颜色也最多只返回8个颜色:
代码语言:javascript复制RColorBrewer::brewer.pal(Inf, "Dark2")
# [1] "#1B9E77" "#D95F02" "#7570B3" "#E7298A" "#66A61E" "#E6AB02" "#A6761D" "#666666"
# Warning message:
# In RColorBrewer::brewer.pal(Inf, "Dark2") :
# n too large, allowed maximum for palette Dark2 is 8
# Returning the palette you asked for with that many colors
如果需要对颜色进行插值可以使用colorRampPalette函数来实现,比如将Dark2配色线性插值成50个颜色:
代码语言:javascript复制par(mfrow = c(2, 1), mar = c(1,1,3,1))
dark2_cols <- RColorBrewer::brewer.pal(8, "Dark2")
showColors(dark2_cols)
showColors(colorRampPalette(dark2_cols)(50))
par(opar)
另外,ggplot2中修改color映射的scale_color_brewer和scale_fill_brewer也可以接受RColorBrewer的配色方案,自动调整颜色,比如:
代码语言:javascript复制library(ggplot2)
library(patchwork)
p <- ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) geom_boxplot()
p2 <- p scale_fill_brewer(palette = "Dark2")
p|p2