204 votes

Comment attribuer des couleurs pour les variables catégorielles dans ggplot2 qui ont stable de la cartographie?

J'ai été d'obtenir jusqu'à la vitesse avec R dans le dernier mois et c'est mon premier post ici. Impatient de rejoindre la communauté. Voici ma question:

Ce qui est une bonne façon d'attribuer des couleurs pour les variables catégorielles dans ggplot2 qui ont stable de la cartographie? J'ai besoin de couleurs cohérentes à travers un ensemble de graphes de différents sous-ensembles et les différents nombre de variables catégorielles.

Par exemple,

plot1 <- ggplot(data, aes(xData, yData,color=categoricaldData)) + geom_line()

categoricalData a 5 niveaux.

Et puis

plot2 <- ggplot(data.subset, aes(xData.subset, yData.subset, 
                                 color=categoricaldData.subset)) + geom_line()

categoricalData.subset a 3 niveaux.

Toutefois, à un niveau particulier qui est dans les deux groupes va se retrouver avec une couleur différente, ce qui rend plus difficile de lire les graphiques associés.

Ai-je besoin de créer un vecteur de couleurs dans le bloc de données? Ou est-il une autre façon de attribue des couleurs aux catégories?

Merci

223voto

joran Points 68079

Pour les situations simples comme l'exemple précis de l'OP, je suis d'accord que Thierry de réponse est le meilleur. Cependant, je pense qu'il est utile de souligner une autre approche qui est plus facile lorsque vous essayez de maintenir la cohérence des couleurs entre plusieurs blocs de données qui ne sont pas tous obtenu par. un seul gros bloc de données. Gérer les facteurs de niveaux dans plusieurs trames de données peut devenir fastidieux si ils sont tirés à partir des fichiers séparés et non tous les niveaux de facteurs apparaissent dans chaque fichier.

Une façon de régler ce problème est de créer un manuel de la couleur de l'échelle comme suit:

#Some test data
dat <- data.frame(x=runif(10),y=runif(10),
        grp = rep(LETTERS[1:5],each = 2),stringsAsFactors = TRUE)

#Create a custom color scale
myColors <- brewer.pal(5,"Set1")
names(myColors) <- levels(dat$grp)
colScale <- scale_colour_manual(name = "grp",values = myColors)

puis ajouter de la couleur à l'échelle sur l'intrigue en tant que de besoin:

#One plot with all the data
p <- ggplot(dat,aes(x,y,colour = grp)) + geom_point()
p1 <- p + colScale

#A second plot with only four of the levels
p2 <- p %+% droplevels(subset(dat[4:10,])) + colScale

La première courbe ressemble à ceci:

enter image description here

et le deuxième tracé ressemble à ceci:

enter image description here

De cette façon, vous n'avez pas besoin de vous rappeler ou de vérifier chaque bloc de données pour voir s'ils ont les niveaux appropriés.

45voto

uvts_cvs Points 4163

Je suis dans la même situation souligné par malcook dans son commentaire: malheureusement, la réponse par Thierry ne fonctionne pas avec ggplot2 version 0.9.3.1.

png("figure_%d.png")
set.seed(2014)
library(ggplot2)
dataset <- data.frame(category = rep(LETTERS[1:5], 100), x = rnorm(500, mean = rep(1:5, 100)), y = rnorm(500, mean = rep(1:5, 100)))
dataset$fCategory <- factor(dataset$category)
subdata <- subset(dataset, category %in% c("A", "D", "E"))

ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()

Ici, c'est la première figure:

enter image description here

et la deuxième figure:

enter image description here

Comme nous pouvons le voir, les couleurs ne restent pas fixes, par exemple E commutateurs de magenta blu.

Comme suggéré par malcook dans son commentaire et par hadley dans son commentaire, le code qui utilise limits fonctionne correctement:

ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point() + scale_colour_discrete(drop=TRUE,limits = levels(dataset$fCategory))

donne la figure suivante est correcte:

enter image description here

C'est la sortie de sessionInfo():

R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] methods   stats     graphics  grDevices utils     datasets  base     

other attached packages:
[1] ggplot2_0.9.3.1

loaded via a namespace (and not attached):
 [1] colorspace_1.2-4   dichromat_2.0-0    digest_0.6.4       grid_3.0.2        
 [5] gtable_0.1.2       labeling_0.2       MASS_7.3-29        munsell_0.4.2     
 [9] plyr_1.8           proto_0.3-10       RColorBrewer_1.0-5 reshape2_1.2.2    
[13] scales_0.2.3       stringr_0.6.2 

18voto

Thierry Points 6246

La solution la plus simple est de convertir votre variable catégorielle à un facteur avant l'.. La ligne de fond est que vous avez besoin d'un facteur variable avec les mêmes niveaux et dans tous vos sous-ensembles.

library(ggplot2)
dataset <- data.frame(category = rep(LETTERS[1:5], 100), x = rnorm(500, mean = rep(1:5, 100)), y = rnorm(500, mean = rep(1:5, 100)))
dataset$fCategory <- factor(dataset$category)
subdata <- subset(dataset, category %in% c("A", "D", "E"))

Avec une variable de caractère

ggplot(dataset, aes(x = x, y = y, colour = category)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = category)) + geom_point()

Avec un facteur variable

ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X