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