ggplot: цветовые точки по группам на основе пользовательских цветов

Я пытаюсь определить цвета групп точек, нанесенных на ggplot. Я адаптировал код из этого поста:

Цветовые точки ggplot на основе определенных цветовых кодов

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

#create some data
zone  <- c("E","E","C","C","C","E","E") #grouping variable
col <- c(50,100,150,200,250,300,350) #x variable
D <- c(.4,.45,.20,.22,.30,.31,.35) #y variable
df1 <- data.frame(zone, D, col); df1

#create a colour scheme based on grouping variable 'zone'
zone <-c("E","C")
color.codes<-as.character(c("#3399FF", "#FF0000"))
color.names<-c("blue", "red")
df2=data.frame(zone, color.codes, color.names); df2

# merge color specifications with data
df <-merge(df1,df2, by=("zone"), all.x=TRUE, all.y=TRUE); df 

Данные тогда выглядят так:

zone    D   col color.codes color.names
C     0.20  150     #FF0000         red
C     0.22  200     #FF0000         red
C     0.30  250     #FF0000         red
E     0.40   50     #3399FF        blue
E     0.45  100     #3399FF        blue
E     0.31  300     #3399FF        blue
E     0.35  350     #3399FF        blue

Цель состоит в том, чтобы создать график, где точки в зоне "C" окрашены в красный цвет, а точки в "E" - в синий, но с использованием кода из приведенного примера все изображено красным:

p <- ggplot(data=df, aes(col, D, colour = zone))+ 
  geom_point() 
p + scale_colour_manual(breaks = df$zone, values = df$color.codes)

Кто-нибудь может увидеть фатальный недостаток, почему этот код не будет работать в группах таким образом?
Большое спасибо заранее

3 ответа

Вы находитесь где-то между двумя разными решениями.

Один из подходов состоит в том, чтобы не помещать цвета в df фрейм данных и указать отображение между zone и желаемый цвет в шкале вызова:

ggplot(data=df, aes(col, D, colour = zone))+ 
  geom_point() +
  scale_colour_manual(values=setNames(color.codes, zone))

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

Обратите внимание, что это не использует color.codes или же color.names от dfи не использует df2 напрямую (хотя он использует столбцы, которые используются для df2; если у вас есть что-то вроде df2 а не столбцы отдельно можно использовать setNames(df2$color.codes, df2$zone) вместо).

Другой подход сопоставляет цвет непосредственно с цветовыми кодами и использует scale_color_identity, но затем нужно пройти некоторые дополнительные маркировки, чтобы получить легенду правильно.

ggplot(data=df, aes(col, D, colour = color.codes)) +
  geom_point() +
  scale_colour_identity("zone", breaks=color.codes, labels=zone, guide="legend")

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

Первое, на мой взгляд, лучшее решение.

Это работает, если вы используете unique а также as.character:

ggplot(data = df, aes(col, D, colour = zone))+ 
  geom_point() +
  scale_colour_manual(breaks = df$zone, 
                      values = unique(as.character(df$color.codes)))

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

Свен избил меня на несколько секунд, но немного по-другому:

df.unique <- unique(df[, c("zone", "color.names")])
p + scale_colour_manual(breaks = df.unique$zone, values = as.character(df.unique$color.names))
Другие вопросы по тегам