# 第 30 章 ggplot2之控制图例的外观

library(tidyverse)
library(palmerpenguins)

penguins <- penguins %>%
drop_na()

## 30.1 使用override.aes的缘由

penguins %>%
ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
geom_point(alpha = .5, size = 1)

### 30.1.1 使用guides()函数

guides(color = guide_legend(override.aes = list(size = 3) ) )
penguins %>%
ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
geom_point(alpha = .5, size = 1) +
guides(color = guide_legend(override.aes = list(size = 3)))

### 30.1.2 使用scale_*()函数

R总是让一件事情，可以有好几种方法完成。上面的效果还可以在scale_*()函数里完成。比如，我们手动设置scale_color_manual()让三种企鹅分别有不同的颜色，然后把上面guide()guide_legend()的代码复制过来

penguins %>%
ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
geom_point(alpha = .5, size = 1) +
scale_color_manual(
values = c("darkorange", "purple", "cyan4"),
guide = guide_legend(override.aes = list(size = 3))
)

### 30.1.3 调整多个美学参数

penguins %>%
ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
geom_point(alpha = .5, size = 1) +
scale_color_manual(
values = c("darkorange", "purple", "cyan4"),
guide = guide_legend(override.aes = list(size = 3, alpha = 1))
)

## 30.2 压缩图例中一部分美学映射

override.aes还有一个用途是，删除图例中一部分美学映射。比如，这里有一个数据集points，points 的id变量有3个分组，

points <- tribble(
~x, ~y, ~id,
5, 51, "a",
10, 54, "a",
7, 50, "a",
9, 60, "a",
86, 97, "b",
46, 74, "b",
22, 59, "b",
94, 68, "b",
21, 45, "c",
6, 56, "c",
24, 25, "c",
3, 70, "c"
)

box <- data.frame(
left   = 1,
right  = 10,
bottom = 50,
top    = 60,
id     = "a"
)
box
##   left right bottom top id
## 1    1    10     50  60  a

points %>%
ggplot(aes(color = id)) +
geom_point(aes(x = x, y = y), size = 4) +
geom_rect(
data = box, aes(
xmin = left,
xmax = right,
ymin = 50,
ymax = top
),
fill = NA, size = 1
)
## Warning: Using size aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use linewidth instead.
## This warning is displayed once every 8 hours.
## Call lifecycle::last_lifecycle_warnings() to see where this warning was
## generated.

points %>%
ggplot(aes(color = id)) +
geom_point(aes(x = x, y = y), size = 4) +
geom_rect(
data = box, aes(
xmin = left,
xmax = right,
ymin = 50,
ymax = top
),
fill = NA, size = 1
) +
guides(color = guide_legend(override.aes = list(linetype = c(1, 0, 0))))

## 30.3 组合两个图层的图例

penguins %>%
ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = factor(species))) +
geom_point(size  = 3) +
geom_smooth(method = "lm", se = FALSE)
## geom_smooth() using formula = 'y ~ x'

### 30.3.1 借鸡下蛋

penguins %>%
ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = factor(species))) +
geom_point(aes(alpha = "Observed"), size = 3) +
geom_smooth(method = "lm", se = FALSE, aes(alpha = "Fitted")) +
scale_alpha_manual(
name = NULL,
values = c(1, 1),
breaks = c("Observed", "Fitted")
)
## geom_smooth() using formula = 'y ~ x'

### 30.3.2 赋予新的图例符号

penguins %>%
ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = factor(species))) +
geom_point(aes(alpha = "Observed"), size = 3) +
geom_smooth(method = "lm", se = FALSE, aes(alpha = "Fitted")) +
scale_alpha_manual(
name = NULL,
values = c(1, 1),
breaks = c("Observed", "Fitted")
) +
guides(alpha = guide_legend(override.aes = list(
linetype = c(0, 1),  # 0无线条； 1有线条
shape = c(16, NA),   # 16点的形状； NA没有点
color = "black"
)))
## geom_smooth() using formula = 'y ~ x'

penguins %>%
ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = factor(species))) +
geom_point(aes(alpha = "Observed"), size = 3) +
geom_smooth(method = "lm", se = FALSE, aes(alpha = "Fitted")) +
scale_alpha_manual(
name = NULL,
values = c(1, 1),
breaks = c("Observed", "Fitted"),
guide = guide_legend(override.aes = list(linetype = c(0, 1),
shape = c(16, NA),
color = "black"))
)
## geom_smooth() using formula = 'y ~ x'

## 30.4 控制多个图例的外观

dat <- tibble::tribble(
~g1,         ~g2,   ~x,   ~y,
"High",   "Control", 0.42, -1.4,
"Low",   "Control", 0.39,  3.6,
"High", "Treatment", 0.56,  1.1,
"Low", "Treatment", 0.59, -0.1,
"High",   "Control", 0.17,  0.5,
"Low",   "Control", 0.95,    0,
"High", "Treatment", 0.85, -1.8,
"Low", "Treatment", 0.25,  0.8,
"High",   "Control", 0.31, -1.1,
"Low",   "Control", 0.75, -0.6,
"High", "Treatment", 0.58,  0.2,
"Low", "Treatment",  0.9,  0.3,
"High",   "Control",  0.6,  1.1,
"Low",   "Control", 0.86,  1.6,
"High", "Treatment", 0.61,  0.9,
"Low", "Treatment", 0.61, -0.6
)

dat %>%
ggplot(aes(x = x, y = y, fill = g1, shape = g2) ) +
geom_point(size = 5)

dat %>%
ggplot(aes(x = x, y = y, fill = g1, shape = g2) ) +
geom_point(size = 5) +
scale_shape_manual(values = c(21, 24) )

dat %>%
ggplot(aes(x = x, y = y, fill = g1, shape = g2) ) +
geom_point(size = 5) +
scale_shape_manual(values = c(21, 24) ) +
guides(fill = guide_legend(override.aes = list(shape = 21)))

dat %>%
ggplot(aes(x = x, y = y, fill = g1, shape = g2) ) +
geom_point(size = 5) +
scale_shape_manual(values = c(21, 24) ) +
guides(fill = guide_legend(override.aes = list(shape = 21) ),
shape = guide_legend(override.aes = list(fill = "black") ) )

## 30.5 课后作业

• 修改下图的图例，希望图例的点透明度为1和形状为方形的点
mtcars %>%
ggplot(aes(vs, am, color = factor(cyl), fill = factor(cyl)) ) +
geom_jitter(alpha = 1/5, size = 2, shape = 21)