web-dev-qa-db-fra.com

ggplot: points de couleur par groupes basés sur des couleurs définies par l'utilisateur

J'essaie de définir les couleurs des groupes de points tracés dans ggplot. J'ai adapté le code de ce post:

Points ggplot de couleur basés sur des codes de couleur définis

mais dès que j'ai plus d'une ligne définie par la même variable de regroupement (plutôt qu'une couleur distincte pour chaque ligne), le code échoue et je ne peux pas comprendre pourquoi. Voici un exemple reproductible:

#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 

Les données ressemblent alors à ceci:

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

Le but est de produire un tracé où les points de la zone "C" sont rouges et ceux de "E" sont bleus, mais en utilisant le code de l'exemple cité, tout est tracé en rouge:

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

Quelqu'un peut-il voir la faille fatale, pourquoi ce code ne fonctionnera-t-il pas entre les groupes de cette façon?
Merci beaucoup d'avance

12
user3267282

Vous êtes quelque part entre deux solutions différentes.

Une approche consiste à ne pas placer les couleurs dans le cadre de données df et à spécifier le mappage entre zone et la couleur souhaitée dans l'appel d'échelle:

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

enter image description here

Notez que cela n'utilise pas color.codes Ou color.names De df, ni qu'il utilise df2 Directement (bien qu'il utilise les colonnes utilisées pour faire df2; Si vous avez quelque chose comme df2 Et non les colonnes séparément, vous pouvez utiliser setNames(df2$color.codes, df2$zone) à la place).

L'autre approche mappe la couleur directement aux codes de couleur et utilise scale_color_identity, Mais doit ensuite passer par un étiquetage supplémentaire pour obtenir la bonne légende.

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

enter image description here

La première est, à mon avis, la meilleure solution.

8
Brian Diggs

Cela fonctionne si vous utilisez unique et 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)))

enter image description here

5
Sven Hohenstein

Sven m'a battu de quelques secondes, mais légèrement différent:

df.unique <- unique(df[, c("zone", "color.names")])
p + scale_colour_manual(breaks = df.unique$zone, values = as.character(df.unique$color.names))
0
BrodieG