上篇主要介绍了RGB模型和灰度模型两种配色方案,本篇来继续介绍HSV模型和HCL模型。
根据色彩理论,色彩具有三要素,即色相、饱和度和明度,HSV模型和HCL模型均是基于该理论的配色方案。
同上篇一样,本篇涉及的函数也都来自grDevices
工具包,具体如下:
hsv()
rgb2hsv()
hcl()
hcl.color()
hcl.pals()
hsv()
hsv()
函数是根据HSV颜色模型生成颜色的,语法结构如下:
hsv(h = 1, s = 1, v = 1, alpha)
h:色调或色相(hue);
s:饱和度或纯度(saturation);
v:明度(value);
aplha:透明度,同
rgb()
函数。
hsv()
函数的四个参数取值范围均是[0,1]。
下面我们通过具体例子,来直观感受三要素的作用效果。
色相(H)
在色彩理论中,一般使用[0, 360]之间的角度来表示色相,这样就可以形成一个色相环,但是R的hsv()
函数的色相参数h
的取值范围为[0,1],在使用时需要进行等比转换。
在色相环中,三原色红、绿、蓝分别占据0、120、240度角,将色相环三等分。相应地,在
hsv()
中,三原色对应的h
参数分别为0、1/3、2/3。
par(plt = c(0,1,0,1))
pie(rep(1,3), init.angle = 90,
labels = "", border = NA,
col = hsv(h = seq(0, 1, 1/3)))
![](https://i-blog.csdnimg.cn/blog_migrate/1a9c0eff850f23e2da81cd9ab34f2cb5.png)
在色相环中,
补色:角度相差180度的色相互为补色,直观地看,即色相环直径的两个端点。相应地,在
hsv()
中,互补色的h
参数相差1/2。在光学中,互补色以一定比例混合可以形成白光;邻近色:角度相差0-60度的色相为邻近色。邻近色的色相彼此近似,冷暖性质一致,色调统一和谐、感情特性一致(来自百度百科);
对比色:角度相差120-180度的色相为对比色。对比色彼此区分明显。
par(plt = c(0,1,0,1),
mfrow = c(1,2))
pie(rep(1,6), init.angle = 90,
labels = "", border = NA,
col = hsv(h = seq(0, 1, 1/6)))
pie(rep(1,24), init.angle = 90,
labels = "", border = NA,
col = hsv(h = seq(0, 1, 1/24)))
![](https://i-blog.csdnimg.cn/blog_migrate/5170425bcfd281fbf10d2523cded5ed3.png)
在R中,通过将上面的饼图无限分割,可以自制一个色相环:
par(plt = c(0,1,0,1))
pie(rep(1,1000), init.angle = 90,
labels = "", border = NA,
col = hsv(h = seq(0, 1, 1/1000)))
![](https://i-blog.csdnimg.cn/blog_migrate/d2f2af7e89c0e0cd0355ea62070fb166.png)
饱和度(S)
前篇介绍过,RGB模型在黑白打印时不太适用,而是需要使用灰度模型。而在HSV模型中,颜色的不同饱和度在黑白打印时会区分成不同的灰度。因此HSV模型生成的颜色在彩印和黑白打印下都可以相互区分。
减小饱和度,相当于是往颜色中加入白色;饱和度也称为纯度。
以红色为例,在hsv()
函数中,固定h
和v
参数(默认值均为1),使饱和度参数s
从0到1进行变化,效果如下:
par(plt = c(0,1,0,1))
pie(rep(1,1000), init.angle = 90,
labels = "", border = NA,
col = hsv(s = seq(0, 1, 1/1000)))
![](https://i-blog.csdnimg.cn/blog_migrate/937c63e02b1e34cae0d3f5dd39232ee5.png)
上图即使在黑白打印时,也能很好区分。
明度(V)
前面几幅图观看起来可能会有些不适,原因在于它们太亮了,即明度太高。
减小明度,相当于往颜色中增加黑色。
同样以红色为例,在hsv()
函数中,固定h
和s
参数(默认值均为1),使明度参数v
从0到1进行变化,效果如下:
par(plt = c(0,1,0,1))
pie(rep(1,1000), init.angle = 90,
labels = "", border = NA,
col = hsv(v = seq(0, 1, 1/1000)))
![](https://i-blog.csdnimg.cn/blog_migrate/e53f0e1f88f5323015a503dd47d91892.png)
可以发现,上图没有前面几幅图那么刺眼;
可视化技巧:在配色时,点状要素一般选择明度较高的颜色,面状要素应选择明度较低的颜色。
par(plt = c(0.15, 0.9, 0.15, 0.95),
mfrow = c(1,2))
# 面要素明度高,点要素明度低
plot(factor(iris$Species), iris$Sepal.Length,
col = hsv(0.5, 0.9, 1))
points(jitter(c(iris$Species)), iris$Sepal.Length,
pch = 21,
bg = hsv(0.2, 1, 0.6))
# 面要素明度低,点要素明度高
plot(factor(iris$Species), iris$Sepal.Length,
col = hsv(0.5, 0.9, 0.6))
points(jitter(c(iris$Species)), iris$Sepal.Length,
pch = 21,
bg = hsv(0.2, 1, 1))
![](https://i-blog.csdnimg.cn/blog_migrate/fab004310d10692d2b96d8fb0de07358.png)
rgb2hsv()
颜色的RGB编码和HSV编码是可以相互转换的,rgb2hsv()
函数提供了将RGB编码转为对应HSV编码的方法。语法结构如下:
rgb2hsv(r, g = NULL, b = NULL,
maxColorValue = 255)
示例:
hsv(0.5, 0.9, 0.6)
## [1] "#0F9999"
col2rgb("#0F9999")
## [,1]
## red 15
## green 153
## blue 153
rgb2hsv(15, 153, 153)
## [,1]
## h 0.5000000
## s 0.9019608
## v 0.6000000
对于同一颜色,HSV编码要比RGB编码更易理解。
hcl()
hcl()
函数是基于HCL颜色模型生成颜色的,它的三个字母分别表示色相(HUe)、饱和度(Chroma)、亮度(Luminance)。
可以看出,HCL模型和HSV模型的参数意义基本类似,但在定义上有略微区别。按照R的官方文档的说法,HCL模型比HSV模型更符合人的视觉感受。
hcl(h = 0, c = 35, l = 85,
alpha, fixup = TRUE)
h:色相参数,意义同
hsv()
函数,但它的取值范围是[0, 360]之间的角度;c:饱和度参数,类似
hsv()
函数的s
参数,但它的取值范围不固定;l:亮度参数,类似
hsv()
函数的v
参数,取值范围为[0, 100]。
在R中,使用HCL模型生成颜色的常用函数实际上是hcl.colors()
,因此这里就不再对hcl()
函数进行介绍了。
hcl.colors()
hcl.colors()
函数的语法结构和功能与grey.colors()
函数类似,即快速生成一组HCL编码的颜色:
hcl.colors(n, palette = "viridis", alpha = NULL,
rev = FALSE, fixup = TRUE)
不同之处是,hcl.colors()
函数拥有一个palette
参数,它指定了彩色调色板的名称,默认调色板为viridis
。
image(x = 1:5, y = 1,
z = matrix(1:5, ncol = 1),
col = hcl.colors(5),
axes = F, ann = F)
![](https://i-blog.csdnimg.cn/blog_migrate/2ba7c05a49bd2829b05d3dfac5c62d10.png)
所有配色板的名称可以通过hcl.pals()
函数进行查询。
hcl.pals()
前面介绍的RColorBrewer
工具包(可点击跳转),其颜色系列分为sequential、qualitative、diverging三类,而hcl.pals()
函数也同样如此,除此之外,还有一个divergingx类型。语法结构如下:
hcl.pals(type = NULL)
type:调色板类型。
hcl.pals("qualitative")
## [1] "Pastel 1" "Dark 2" "Dark 3" "Set 2" "Set 3" "Warm" "Cold"
## [8] "Harmonic" "Dynamic"
hcl.pals("sequential")
## [1] "Grays" "Light Grays" "Blues 2" "Blues 3"
## [5] "Purples 2" "Purples 3" "Reds 2" "Reds 3"
## [9] "Greens 2" "Greens 3" "Oslo" "Purple-Blue"
## [13] "Red-Purple" "Red-Blue" "Purple-Orange" "Purple-Yellow"
## [17] "Blue-Yellow" "Green-Yellow" "Red-Yellow" "Heat"
## [21] "Heat 2" "Terrain" "Terrain 2" "Viridis"
## [25] "Plasma" "Inferno" "Dark Mint" "Mint"
## [29] "BluGrn" "Teal" "TealGrn" "Emrld"
## [33] "BluYl" "ag_GrnYl" "Peach" "PinkYl"
## [37] "Burg" "BurgYl" "RedOr" "OrYel"
## [41] "Purp" "PurpOr" "Sunset" "Magenta"
## [45] "SunsetDark" "ag_Sunset" "BrwnYl" "YlOrRd"
## [49] "YlOrBr" "OrRd" "Oranges" "YlGn"
## [53] "YlGnBu" "Reds" "RdPu" "PuRd"
## [57] "Purples" "PuBuGn" "PuBu" "Greens"
## [61] "BuGn" "GnBu" "BuPu" "Blues"
## [65] "Lajolla" "Turku"
hcl.pals("diverging")
## [1] "Blue-Red" "Blue-Red 2" "Blue-Red 3" "Red-Green"
## [5] "Purple-Green" "Purple-Brown" "Green-Brown" "Blue-Yellow 2"
## [9] "Blue-Yellow 3" "Green-Orange" "Cyan-Magenta" "Tropic"
## [13] "Broc" "Cork" "Vik" "Berlin"
## [17] "Lisbon" "Tofino"
hcl.pals("divergingx")
## [1] "ArmyRose" "Earth" "Fall" "Geyser" "TealRose" "Temps"
## [7] "PuOr" "RdBu" "RdGy" "PiYG" "PRGn" "BrBG"
## [13] "RdYlBu" "RdYlGn" "Spectral" "Zissou 1" "Cividis"
hcl.pals()
函数中共有110种调色板,远远多于RColorBrewer
工具包;可以发现,
RColorBrewer
工具包中的颜色系列名称也可以在hcl.pals()
函数中找到。
image(x = 1:12, y = 1,
z = matrix(1:12, ncol = 1),
col = hcl.colors(12, palette = "Reds"),
axes = F, ann = F)
![](https://i-blog.csdnimg.cn/blog_migrate/f893bd9caab2ac6c2fca3ce330ea147d.png)
使用
hcl.colors()
函数调用调色板生成颜色是没有数量限制的,而RColorBrewer
工具包的颜色系列所包含的颜色都具有上限。
col <- hcl.colors(5, palette = "Reds")
rgbcode <- col2rgb(col)
rgb2hsv(rgbcode)
## [,1] [,2] [,3] [,4] [,5]
## h 0.941896 0.9737828 0.02291667 0.04065041 0.05000000
## s 1.000000 0.8725490 0.62745098 0.32156863 0.03968254
## v 0.427451 0.8000000 1.00000000 1.00000000 0.98823529
可以看出,使用
hcl.colors()
函数生成的颜色的色相、饱和度和亮度均有一定的区别,因此可以用于彩色和黑白印刷,而无需额外的调整。