R 數(shù)據(jù)可視化 —— ggplot 標(biāo)度(四)配色

10. 顏色

除了前面講的位置標(biāo)度之外,最常用的就是顏色屬性的修改了。

配色也是一門藝術(shù),像我這種沒有藝術(shù)細(xì)胞的人就只能看著哪種配色方案漂亮就將就著用了????

10.1 ColorBrewer 配色

ColorBrewer 提供了 sequential, divergingqualitative 三種不同的配色類型,每種類型又有不同的配色方案。

有三個(gè)不同的標(biāo)度函數(shù)來設(shè)置

# 針對離散型數(shù)據(jù)
scale_*_brewer()
# 針對連續(xù)型數(shù)據(jù)
scale_*_distiller()
# 針對分箱數(shù)據(jù)
scale_*_fermenter()

其中 * 代表 colour(輪廓顏色) 和 fill(填充色)。

palette 參數(shù)的值可以是下列字符串之一

  1. Diverging(雙色漸變系)
BrBG, PiYG, PRGn, PuOr, RdBu, RdGy, RdYlBu, RdYlGn, Spectral
  1. Qualitative(多色系)
Accent, Dark2, Paired, Pastel1, Pastel2, Set1, Set2, Set3
  1. 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)頁:

http://colorbrewer2.org

配色好看,獲取簡單,推薦使用

還有一個(gè)網(wǎng)站
https://www.webdesignrankings.com/resources/lolcolors/

配色也還可以,只是都是 4 種顏色的。

10.2 漸變色

根據(jù)顏色梯度,可以將設(shè)置漸變色的函數(shù)分為三種:

  • scale_*_gradient:雙色漸變,使用 lowhigh 兩個(gè)參數(shù)控制兩端的顏色

  • scale_*_gradient2:三色漸變,有 lowmidhigh 三個(gè)參數(shù),lowhigh 作用同上,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 灰色漸變

使用 startend 控制灰度范圍

示例

默認(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.colourggplot2.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)

可以看到,AC,BD 是一樣的。

離散型

類似于連續(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.colourggplot2.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í)使用的是 skyblueorange,有 3 個(gè) level 使用 Set2 配色,4-6 個(gè) level 使用 Accent 配色。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容