10. 顏色
除了前面講的位置標(biāo)度之外,最常用的就是顏色屬性的修改了。
配色也是一門藝術(shù),像我這種沒有藝術(shù)細(xì)胞的人就只能看著哪種配色方案漂亮就將就著用了????
10.1 ColorBrewer 配色
ColorBrewer 提供了 sequential, diverging 和 qualitative 三種不同的配色類型,每種類型又有不同的配色方案。
有三個(gè)不同的標(biāo)度函數(shù)來設(shè)置
# 針對離散型數(shù)據(jù)
scale_*_brewer()
# 針對連續(xù)型數(shù)據(jù)
scale_*_distiller()
# 針對分箱數(shù)據(jù)
scale_*_fermenter()
其中 * 代表 colour(輪廓顏色) 和 fill(填充色)。
palette 參數(shù)的值可以是下列字符串之一
-
Diverging(雙色漸變系)
BrBG, PiYG, PRGn, PuOr, RdBu, RdGy, RdYlBu, RdYlGn, Spectral
-
Qualitative(多色系)
Accent, Dark2, Paired, Pastel1, Pastel2, Set1, Set2, Set3
-
Sequential(單色系)
Blues, BuGn, BuPu, GnBu, Greens, Greys, Oranges, OrRd, PuBu, PuBuGn, PuRd, Purples, RdPu, Reds, YlGn, YlGnBu, YlOrBr, YlOrRd

示例
對于如下數(shù)據(jù)
dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
我們可以為 colour 設(shè)置變量
(d <- ggplot(dsamp, aes(carat, price)) +
geom_point(aes(colour = clarity)))

但是我覺得這種配色不太好看,想換一種。我們進(jìn)行如下嘗試
p1 <- d + scale_colour_brewer()
p2 <- d + scale_colour_brewer(palette = "Greens")
p3 <- d + scale_colour_brewer(palette = "Set1")
p4 <- d + scale_colour_brewer(palette = "Spectral")
plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

en...,這樣來看,圖 C 是比較好看的,圖 D 看起來也行,單色系的就差了點(diǎn)嘍。
連續(xù)型數(shù)據(jù)的設(shè)置方式也是類似的
d1 <- ggplot(dsamp, aes(carat, price)) +
geom_point(aes(colour = depth))
d2 <- d + scale_colour_distiller(palette = "Greens")
d3 <- d + scale_colour_distiller(palette = "Set1")
d4 <- d + scale_colour_distiller(palette = "Spectral")
plot_grid(d1, d2, d3, d4, labels = LETTERS[1:4], nrow = 2)

為分箱數(shù)據(jù)配色
ggplot(dsamp, aes(carat, price)) +
geom_point(aes(colour=depth)) +
scale_colour_fermenter(palette = "Spectral")

為每個(gè)分箱設(shè)置顏色相同的配色
ggplot(dsamp, aes(carat, price, colour=price)) +
geom_point() +
scale_x_binned() +
scale_colour_fermenter(palette = "Spectral")

獲取更多的配色方案,可以訪問 ColorBrewer 的網(wǎng)頁:

配色好看,獲取簡單,推薦使用
還有一個(gè)網(wǎng)站
https://www.webdesignrankings.com/resources/lolcolors/

配色也還可以,只是都是 4 種顏色的。
10.2 漸變色
根據(jù)顏色梯度,可以將設(shè)置漸變色的函數(shù)分為三種:
scale_*_gradient:雙色漸變,使用low和high兩個(gè)參數(shù)控制兩端的顏色scale_*_gradient2:三色漸變,有low、mid和high三個(gè)參數(shù),low和high作用同上,mid默認(rèn)值為0表示中點(diǎn)的顏色,可以使用midpoint參數(shù)設(shè)置中點(diǎn)位置scale_*_gradientn:多色漸變,為colours參數(shù)設(shè)置一個(gè)顏色向量,不加其他參數(shù)會選擇范圍內(nèi)的均勻分布值,離散型顏色可以指定values參數(shù)。
示例
對于如下數(shù)據(jù)
df <- data.frame(
x = runif(100),
y = runif(100),
z1 = rnorm(100),
z2 = abs(rnorm(100))
)
df_na <- data.frame(
value = seq(1, 20),
x = runif(20),
y = runif(20),
z1 = c(rep(NA, 10), rnorm(10))
)
其默認(rèn)配色為淺藍(lán)色到深藍(lán)色的雙色漸變
# 默認(rèn)雙色漸變
p1 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z2))
# 調(diào)整雙色漸變區(qū)間
p2 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z2)) +
scale_colour_gradient(low = "white", high = "black")
# 三色漸變
p3 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z1)) +
scale_colour_gradient2()
# 調(diào)整三色漸變區(qū)間
p4 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z1)) +
scale_colour_gradient2(low = "green", high = "blue", midpoint = 1)
plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

自定義顏色范圍,以及 NA 值的處理
# 自定義顏色范圍,使用函數(shù)來生成 10 個(gè)連續(xù)的顏色
p5 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z1)) +
scale_colour_gradientn(colours = topo.colors(10))
p6 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z1)) +
scale_colour_gradientn(colours = rainbow(10))
# 去除 NA 值
p7 <- ggplot(df_na, aes(x = value, y)) +
geom_bar(aes(fill = z1), stat = "identity") +
scale_fill_gradient(low = "yellow", high = "red", na.value = NA)
p8 <- ggplot(df_na, aes(x, y)) +
geom_point(aes(colour = z1)) +
scale_colour_gradient(low = "yellow", high = "red", na.value = NA)
plot_grid(p5, p6, p7, p8, labels = LETTERS[1:4], nrow = 2)

10.3 灰色漸變
使用 start 和 end 控制灰度范圍
示例
默認(rèn)顏色
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(colour = factor(cyl)))
p + scale_colour_grey()

更改設(shè)置
# 設(shè)置終端灰度
p1 <- p + scale_colour_grey(end = 0.5)
# 更改主題
p2 <- p + scale_colour_grey() + theme_bw()
# 缺失值
miss <- factor(sample(c(NA, 1:5), nrow(mtcars), replace = TRUE))
p3 <- ggplot(mtcars, aes(mpg, wt)) +
geom_point(aes(colour = miss)) +
scale_colour_grey()
# 更改缺失值的顏色
p4 <- ggplot(mtcars, aes(mpg, wt)) +
geom_point(aes(colour = miss)) +
scale_colour_grey(na.value = "green")
plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

10.4 分箱漸變色
分箱漸變色與漸變色類似,只是應(yīng)用的數(shù)據(jù)不同。也有三個(gè)函數(shù),對應(yīng)于雙色、三色以及多色漸變
scale_*_steps()
scale_*_steps2()
scale_*_stepsn()
用起來和漸變色很相似
df <- data.frame(
x = runif(100),
y = runif(100),
z1 = rnorm(100)
)
p1 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z1))
p2 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z1)) +
scale_colour_steps(low = "skyblue", high = "blue")
p3 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z1)) +
scale_colour_steps2()
p4 <- ggplot(df, aes(x, y)) +
geom_point(aes(colour = z1)) +
scale_colour_stepsn(colours = terrain.colors(10))
plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

10.5 色輪顏色
這種設(shè)置方式主要用于將離散型數(shù)據(jù)均勻地映射到色輪上的顏色。
這種配色方案被稱為 HLC,包含三部分:
色相(
hue):0-360之間的值(代表角度),代表顏色。如紅、黃、藍(lán)等亮度(
luminance):表示顏色的明亮程度,0表示黑色,100表示白色色度(
chroma):顏色的純度,色度為0表示灰色,最大值根據(jù)色相和亮度的組合而變化
而標(biāo)度函數(shù)
scale_*_hue(
...
h = c(0, 360) + 15,
c = 100,
l = 65,
)
有對應(yīng)的參數(shù) h、c、l 用于設(shè)置這些值。
示例
dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
d <- ggplot(dsamp, aes(carat, price)) +
geom_point(aes(colour = clarity))
p1<- d + scale_colour_hue()
p2 <- d + scale_colour_hue("Clarity")
p3 <- d + scale_colour_hue(expression(clarity[beta]))
d + scale_colour_hue(l = 40, c = 30)
plot_grid(d, p1, p2, p3, labels = LETTERS[1:4], nrow = 2)

調(diào)整亮度和色相
p1 <- d + scale_colour_hue(l = 40, c = 30)
p2 <- d + scale_colour_hue(l = 70, c = 30)
p3 <- d + scale_colour_hue(l = 70, c = 150)
p4 <- d + scale_colour_hue(l = 80, c = 150)
plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

設(shè)置色相的范圍
p1 <- d + scale_colour_hue(h = c(0, 90))
p2 <- d + scale_colour_hue(h = c(90, 180))
p3 <- d + scale_colour_hue(h = c(180, 270))
p4 <- d + scale_colour_hue(h = c(270, 360))
plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

設(shè)置透明度
d <- ggplot(dsamp, aes(carat, price, colour = clarity))
p2 <- d + geom_point(alpha = 0.9)
p3 <- d + geom_point(alpha = 0.5)
p4 <- d + geom_point(alpha = 0.2)
plot_grid(p2, p3, p4, labels = LETTERS[1:4], nrow = 3)

這個(gè)圖設(shè)置透明度之后好看多了
給 NA 值設(shè)置特殊的顏色
miss <- factor(sample(c(NA, 1:5), nrow(mtcars), replace = TRUE))
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(colour = miss))
p2 <- ggplot(mtcars, aes(mpg, wt)) +
geom_point(aes(colour = miss)) +
scale_colour_hue(na.value = "black")
plot_grid(p1, p2, labels = LETTERS[1:4], nrow = 2)

10.6 Viridis 配色
viridis 提供的顏色映射,讓無論是在彩色還是黑白圖片均能夠很容易看出區(qū)別。
它還被設(shè)計(jì)能夠讓色盲觀眾也能看清
示例
對于如下數(shù)據(jù)
> dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
> dsamp
# A tibble: 1,000 x 10
carat cut color clarity depth table price x y z
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 1.01 Very Good E SI1 62.1 56 5461 6.43 6.48 4.01
2 0.91 Premium F SI2 61.7 58 3609 6.22 6.29 3.86
3 1.26 Very Good H SI1 60.6 60 6546 6.97 7 4.23
4 1.31 Premium H VS2 61.4 59 7550 7.01 6.96 4.29
5 1.53 Very Good D SI1 59.2 57 11873 7.52 7.55 4.46
6 1.5 Ideal H SI2 62.4 58 8471 7.29 7.26 4.54
7 1.24 Premium F VS1 61.5 57 9333 6.97 6.86 4.25
8 1.14 Premium H SI1 59.3 59 5458 6.8 6.76 4.02
9 0.62 Very Good E SI2 63.4 56 1426 5.4 5.45 3.44
10 0.72 Premium G VS2 62.9 57 2795 5.73 5.65 3.58
# … with 990 more rows
默認(rèn)的顏色設(shè)置方式會根據(jù)因子的順序上色
ggplot(dsamp, aes(carat, price)) +
geom_point(aes(colour = clarity))

viridis_d 函數(shù)用于離散數(shù)據(jù)配色,可以使用 option 參數(shù)設(shè)置不同的調(diào)色板
# viridis_d 用于離散數(shù)據(jù)
txsamp <- subset(txhousing, city %in%
c("Houston", "Fort Worth", "San Antonio", "Dallas", "Austin"))
d <- ggplot(data = txsamp, aes(x = sales, y = median)) +
geom_point(aes(colour = city))
# 設(shè)置配色和標(biāo)簽
p1 <- d + scale_colour_viridis_d("City\nCenter")
# 選擇調(diào)色板,使用 ?scales::viridis_pal 獲取更多細(xì)節(jié)
p2 <- d + scale_colour_viridis_d(option = "plasma")
p3 <- d + scale_colour_viridis_d(option = "inferno")
plot_grid(d, p1, p2, p3, labels = LETTERS[1:4], nrow = 2)

設(shè)置填充色
# 設(shè)置填充色
p <- ggplot(txsamp, aes(x = median, fill = city)) +
geom_histogram(position = "dodge", binwidth = 15000)
p1 <- p + scale_fill_viridis_d()
# 反轉(zhuǎn)顏色
p2 <- p + scale_fill_viridis_d(direction = -1)
plot_grid(p1, p2, labels = LETTERS[1:4], nrow = 2)

連續(xù)型數(shù)據(jù)及分箱數(shù)據(jù)顏色設(shè)置
# 連續(xù)型數(shù)據(jù)
v <- ggplot(faithfuld) +
geom_tile(aes(waiting, eruptions, fill = density))
p2 <- v + scale_fill_viridis_c()
p3 <- v + scale_fill_viridis_c(option = "plasma")
# 分箱數(shù)據(jù)
p4 <- v + scale_fill_viridis_b()
plot_grid(v, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

10.6 連續(xù)型和離散型
其實(shí)使用上面的函數(shù)已經(jīng)夠了,下面的操作也只是對上面的函數(shù)進(jìn)行整合,功能都是一樣的。
連續(xù)型
對于連續(xù)型數(shù)據(jù)的配色方案,其實(shí)我們上面也都涉及到。在這里我們要使用的是下面兩個(gè)函數(shù)
scale_colour_continuous(
...,
type = getOption("ggplot2.continuous.colour", default = "gradient")
)
scale_fill_continuous(
...,
type = getOption("ggplot2.continuous.fill", default = "gradient")
)
這兩個(gè)函數(shù)主要是通過獲取 ggplot2.continuous.colour 和 ggplot2.continuous.fill 兩個(gè)選項(xiàng)的值來設(shè)置顏色的,默認(rèn)是漸變色
type 參數(shù)還可以設(shè)置為:
"viridis"- 返回連續(xù)顏色向量的函數(shù)
示例
對于如下數(shù)據(jù)
> faithfuld
# A tibble: 5,625 x 3
eruptions waiting density
<dbl> <dbl> <dbl>
1 1.6 43 0.00322
2 1.65 43 0.00384
3 1.69 43 0.00444
4 1.74 43 0.00498
5 1.79 43 0.00542
6 1.84 43 0.00574
7 1.88 43 0.00592
8 1.93 43 0.00594
9 1.98 43 0.00581
10 2.03 43 0.00554
# … with 5,615 more rows
我們可以繪制一張熱圖
v <- ggplot(faithfuld, aes(waiting, eruptions, fill = density)) +
geom_tile()

更改顏色方案
p1 <- v + scale_fill_continuous(type = "gradient")
p2 <- v + scale_fill_continuous(type = "viridis")
p3 <- v + scale_fill_gradient()
p4 <- v + scale_fill_viridis_c()
plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

可以看到,A 與 C,B 與 D 是一樣的。
離散型
類似于連續(xù)型設(shè)置顏色的函數(shù),離散型函數(shù)也是通過獲取兩個(gè)選項(xiàng)的值來設(shè)置顏色的
scale_colour_discrete(
...,
type = getOption("ggplot2.discrete.colour", getOption("ggplot2.discrete.fill"))
)
scale_fill_discrete(
...,
type = getOption("ggplot2.discrete.fill", getOption("ggplot2.discrete.colour"))
)
例如,我們要繪制如下圖形
ggplot(mpg, aes(cty, colour = factor(class), fill = factor(class))) +
geom_density(alpha = 0.2)
默認(rèn)是以 scale_fill_hue() 配色方案

使用 scale_*_discrete 來更改配色
okabe <- c("#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")
ggplot(mpg, aes(cty, colour = factor(class), fill = factor(class))) +
geom_density(alpha = 0.2) +
scale_color_discrete(type = okabe) +
scale_fill_discrete(type = okabe)

也可以通過設(shè)置 ggplot2.discrete.colour 或 ggplot2.discrete.fill 的值來更改配色
withr::with_options(
list(ggplot2.discrete.fill = okabe),
print(plot_cty(class))
)

還可以根據(jù)顏色變量的取值數(shù)目,設(shè)置默認(rèn)的配色
discrete_palettes <- list(
c("skyblue", "orange"),
RColorBrewer::brewer.pal(3, "Set2"),
RColorBrewer::brewer.pal(6, "Accent")
)
p1 <- plot_cty(year) + scale_fill_discrete(type = discrete_palettes)
p2 <- plot_cty(drv) + scale_fill_discrete(type = discrete_palettes)
p3 <- plot_cty(fl) + scale_fill_discrete(type = discrete_palettes)
# 也可以傳遞返回離散顏色的函數(shù)
p4 <- plot_cty(class) + scale_fill_discrete(type = scale_fill_brewer)
plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], nrow = 2)

在上面的例子中(圖 A-C),我們在列表中根據(jù)離散數(shù)據(jù)的取值數(shù)目(因子的 level)設(shè)置不同的配色。
在只有 1-2 個(gè) level 時(shí)使用的是 skyblue 和 orange,有 3 個(gè) level 使用 Set2 配色,4-6 個(gè) level 使用 Accent 配色。