问题描述
假设数据如下:
library(tidyverse)
library(ggrepel)
df <- data.frame(name = rep(letters[1:3],3),points = c(5,3,7,12,13,14,20,30,40),time = rep(c("day 1","day 2","day 3"),each = 3))
df2 <- df %>%
group_by(name) %>%
mutate(points_sum = cumsum(points)) %>%
group_by(time) %>%
mutate(rank = rank(desc(points_sum),ties.method = "min")) %>%
ungroup() %>%
mutate(name_colour = case_when(rank == 1 ~ "#336600",rank == 2 ~ "#339900",rank == 3 ~ "#66ff33"))
我现在想绘制以下图,即为名称/标签指定在 name_colour
列中指定的颜色:
df2 %>%
ggplot(aes(x = time,y = points_sum,group = name,label = name)) +
geom_point() +
geom_text_repel(direction = "y",size = 10,colour = df2$name_colour) +
theme_minimal()
但是,此图缺少这些颜色的图例,即我想添加一个图例,该图例在相应颜色旁边具有排名。
我不确定如何在这里手动添加这样的图例。我试图通过下面的代码更改上面的代码(仅在倒数第二行中更改),但这完全改变了标签的颜色:
df2 %>%
ggplot(aes(x = time,aes(colour = name_colour)) +
theme_minimal()
有什么想法吗?
解决方法
如果您想使用数据框中的颜色代码,请使用 scale_color_identity
。默认情况下,这不会为您提供图例,因此您必须添加 guide = guide_legend()
:
library(tidyverse)
library(ggrepel)
df <- data.frame(
name = rep(letters[1:3],3),points = c(5,3,7,12,13,14,20,30,40),time = rep(c("day 1","day 2","day 3"),each = 3)
)
df2 <- df %>%
group_by(name) %>%
mutate(points_sum = cumsum(points)) %>%
group_by(time) %>%
mutate(rank = rank(desc(points_sum),ties.method = "min")) %>%
ungroup() %>%
mutate(name_colour = case_when(
rank == 1 ~ "#336600",rank == 2 ~ "#339900",rank == 3 ~ "#66ff33"
))
df2 %>%
ggplot(aes(
x = time,y = points_sum,group = name,label = name
)) +
geom_point() +
geom_text_repel(aes(color = name_colour),direction = "y",size = 10) +
scale_color_identity(labels = c("A","B","C"),guide = guide_legend()) +
theme_minimal()
,
总的来说,我认为更典型的 ggplot 方法是在 scale_colour_manual
或等效项中指定颜色,而不是将它们编码到数据框本身中。例如:
library(ggplot2)
library(dplyr)
library(ggrepel)
data.frame(
name = rep(letters[1:3],each = 3)
) %>%
group_by(name) %>%
mutate(points_sum = cumsum(points)) %>%
group_by(time) %>%
mutate(rank = factor(rank(desc(points_sum),ties.method = "min"))) %>%
ungroup() %>%
ggplot(aes(
x = time,y = points_sum,label = name)) +
geom_point() +
geom_text_repel(direction = "y",size = 10,aes(colour = rank)) +
theme_minimal() +
scale_colour_manual(
values = c("1" = "#336600","2" = "#339900","3" = "#66ff33")
)