Используйте пользовательский цвет И пользовательскую метку из столбцов фрейма данных в ggplot2

#r #ggplot2

Вопрос:

Я хотел бы, чтобы ggplot взял цвет и эстетику этикетки из строящегося фрейма данных. Я понимаю, что вы можете использовать scale_colour_identity() для получения цвета из data.frame ( col столбец ниже), но я не уверен, как заставить его также читать пользовательские метки ( lab столбец ниже).

Примечание: Я ценю, что вы можете сделать это, жестко закодировав метки и цвета сценария (набор manual команд в ggplot). Тем не менее, я хочу избежать жесткого кодирования этих вещей в сценарии R (что мне кажется плохой практикой кодирования), потому что мне сложнее использовать те же метаданные построения в сценарии Python (или другом сценарии R), например. Я ценю, что вы также можете добавить цвета в сценарий R и использовать их в качестве источника (), но тогда возникает та же проблема при попытке использовать согласованные цвета в графиках Python.

 require(ggplot2)

set.seed(42)

# Define test dataset
n_trt <- 3
n_samples <- 5
cols <- c("#F2762E", "#F2AB27", "#4F8C11")

df <- data.frame(
    trt = rep(LETTERS[1:n_trt], each = n_samples),
    response_x = rep(rnorm(n_trt), each = n_samples)   runif(n_trt*n_samples),
    response_y = rep(rnorm(n_trt), each = n_samples)   runif(n_trt*n_samples),
    col = rep(cols, each = n_samples),
    lab = rep(paste0(LETTERS[1:n_trt], letters[1:n_trt]), each = n_samples))

#> print(head(df))
#  trt response_x response_y     col lab
#1   A  2.1075468 -0.1803944 #F2762E  Aa
#2   A  1.5056250 -0.6391629 #F2762E  Aa
#3   A  2.0279507 -0.2501283 #F2762E  Aa
#4   A  2.0760232 -0.3485370 #F2762E  Aa
#5   A  1.8287002 -0.2750774 #F2762E  Aa
#6   B  0.1544141  2.0014811 #F2AB27  Bb

# Plotting routine
p <- ggplot(df, aes(x = response_x, y = response_y, 
        color = col, labels = lab, group = lab))   
    geom_point(size = 2.5)   
    scale_colour_identity(guide = "legend", aes(labels = lab))   
    theme_bw()   
    theme(legend.position = "top")

ggsave("test.png", p, width = 6, height = 4)
 

тест.png

Ответ №1:

введите описание изображения здесь

Управляйте своими надписями с помощью отдельного слоя.
Чтобы метки не перекрывались с вашими точками, вы можете смещать их с помощью nudge_x или nudge_y.

Если у вас возникнут проблемы с перекрывающимися метками, ознакомьтесь с geom_text_repel().

 p <- ggplot(df, aes(x = response_x, y = response_y, 
                    color = col, labels = lab, group = lab))   
    geom_point(size = 2.5)   
    geom_text(aes(label = lab), nudge_x = 0.2)  
    scale_colour_identity(guide = "legend", aes(labels = lab))   
    theme_bw()   
    theme(legend.position = "top")
p
 

Комментарии:

1. Спасибо за комментарий. Я искал общее решение, в котором они помечены в легенде (например, test.png в вопросе). Добавление меток на рисунке неприменимо для других геом (например, линий) или в нетривиальных наборах данных, содержащих 100 точек.

2. нет проблем @p-робот. Вы заметили решение своей проблемы, которое не было очевидно из вашего вопроса. Здорово.

Ответ №2:

Можно использовать unique() с _manual_ набором функций, но это зависит от упорядоченного поведения unique() , которое не является идеальным.

 df$col <- as.character(df$col)
df$lab <- as.character(df$lab)

# Plotting routine
p <- ggplot(df, aes(x = response_x, y = response_y, group = lab))   
    geom_point(aes(color = lab), size = 2.5)   
    theme_bw()   
    scale_color_manual(name = "", values = unique(df$col), labels = unique(df$lab))   
    theme(legend.position = "top")

ggsave("test.png", p, width = 6, height = 4)
 

тест.png

Комментарии:

1. в принципе, вы нашли способ сделать это. Имейте в виду, что вы можете предоставить values и labels то, что хотите контролировать _manual . Таким образом, вы можете задать значения/метки с помощью вектора. Очевидно, что это делается вручную, и такая функция, как unique (), не поможет. Но вы можете работать с факторами или упорядочивать векторные элементы по-другому. Надеюсь, это поможет.

Ответ №3:

Вместо использования unique() вы можете передать нужные цвета и метки в виде именованного вектора scale_color_manual , который гарантирует, что цвета будут назначены правильным категориям. Поскольку у вас есть цвета и метки внутри фрейма данных, вы можете использовать dplyr::distinct и tibble::deframe создавать именованные векторы таким образом:

 require(ggplot2)
library(dplyr)

cols <- dplyr::distinct(df, trt, col) %>% tibble::deframe()
cols
#>         A         B         C 
#> "#F2762E" "#F2AB27" "#4F8C11"
labs <- dplyr::distinct(df, trt, lab) %>% tibble::deframe()
labs
#>    A    B    C 
#> "Aa" "Bb" "Cc"

# Plotting routine
ggplot(df, aes(x = response_x, y = response_y, color = trt))   
  geom_point(size = 2.5)   
  scale_colour_manual(values = cols, labels = labs)   
  theme_bw()   
  theme(legend.position = "top")