ggplot2 + ggrepel 添加带有标签颜色的图例会改变颜色本身

问题描述

假设数据如下:

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()

Build Output Statistics

但是,此图缺少这些颜色的图例,即我想添加一个图例,该图例在相应颜色旁边具有排名。

我不确定如何在这里手动添加这样的图例。我试图通过下面的代码更改上面的代码(仅在倒数第二行中更改),但这完全改变了标签的颜色:

df2 %>%
  ggplot(aes(x     = time,aes(colour = name_colour)) +
  theme_minimal() 

Plot without legend

有什么想法吗?

解决方法

如果您想使用数据框中的颜色代码,请使用 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")
        )

plt

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...