Je me suis familiarisé avec R au cours du dernier mois.
Voici ma question:
Quel est un bon moyen d'attribuer des couleurs aux variables catégoriques dans ggplot2 qui ont un mapping stable? J'ai besoin de couleurs cohérentes sur un ensemble de graphiques comportant différents sous-ensembles et un nombre différent de variables catégorielles.
Par exemple,
plot1 <- ggplot(data, aes(xData, yData,color=categoricaldData)) + geom_line()
où categoricalData
a 5 niveaux.
Puis
plot2 <- ggplot(data.subset, aes(xData.subset, yData.subset,
color=categoricaldData.subset)) + geom_line()
où categoricalData.subset
a 3 niveaux.
Cependant, un niveau particulier qui se trouve dans les deux ensembles se retrouvera avec une couleur différente, ce qui rend plus difficile la lecture simultanée des graphiques.
Dois-je créer un vecteur de couleurs dans le bloc de données? Ou existe-t-il un autre moyen d'attribuer des couleurs spécifiques à des catégories?
Pour des situations simples comme l'exemple exact du PO, je conviens que la réponse de Thierry est la meilleure. Cependant, je pense qu'il est utile de souligner une autre approche qui devient plus facile lorsque vous essayez de maintenir des schémas de couleurs cohérents sur plusieurs trames de données qui sont non toutes obtenues en sous-configurant un seul grand cadre de données. La gestion des niveaux de facteurs dans plusieurs blocs de données peut devenir fastidieuse si ceux-ci sont extraits de fichiers distincts et si tous les niveaux de facteurs n'apparaissent pas dans chaque fichier.
Une façon de résoudre ce problème consiste à créer une échelle de couleurs manuelle personnalisée, 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
library(RColorBrewer)
myColors <- brewer.pal(5,"Set1")
names(myColors) <- levels(dat$grp)
colScale <- scale_colour_manual(name = "grp",values = myColors)
puis ajoutez l’échelle de couleur sur la parcelle au 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 parcelle ressemble à ceci:
et la deuxième parcelle ressemble à ceci:
De cette façon, vous n'avez pas besoin de vous souvenir ou de vérifier chaque trame de données pour voir qu'ils ont les niveaux appropriés.
Je suis dans la même situation que celle indiquée par malcook dans son commentaire : malheureusement le 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 le premier chiffre:
et la deuxième figure:
Comme on peut le constater, les couleurs ne restent pas fixes. Par exemple, E passe de Magenta à Bleu.
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 le chiffre suivant, qui est correct:
Voici le résultat 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
La solution la plus simple consiste à convertir votre variable catégorielle en un facteur antérieur au sous-ensemble. En bout de ligne, vous avez besoin d’une variable de facteur avec exactement les mêmes niveaux 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 une variable facteur
ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()
Sur la base de la réponse très utile de Joran, j'ai pu proposer cette solution pour une échelle de couleurs stable pour un facteur booléen (TRUE
, FALSE
).
boolColors <- as.character(c("TRUE"="#5aae61", "FALSE"="#7b3294"))
boolScale <- scale_colour_manual(name="myboolean", values=boolColors)
ggplot(myDataFrame, aes(date, duration)) +
geom_point(aes(colour = myboolean)) +
boolScale
Etant donné que ColorBrewer n’est pas très utile avec les échelles de couleurs binaires, les deux couleurs nécessaires sont définies manuellement.
Ici, myboolean
est le nom de la colonne dans myDataFrame
contenant le facteur TRUE/FALSE. date
et duration
sont les noms de colonne à mapper sur les axes x et y du tracé dans cet exemple.
Ceci est un ancien post, mais je cherchais une réponse à cette même question,
Pourquoi ne pas essayer quelque chose comme:
scale_color_manual(values = c("foo" = "#999999", "bar" = "#E69F00"))
Si vous avez des valeurs catégoriques, je ne vois pas pourquoi cela ne fonctionnerait pas.