¿Cómo asignar colores a las variables categóricas en ggplot2 que tienen un mapeo estable?

Me he estado poniendo al día con R en el último mes.

Aquí está mi pregunta:

¿Cuál es una buena manera de asignar colores a las variables categóricas en ggplot2 que tienen un mapeo estable? Necesito colores uniformes en un conjunto de gráficos que tienen diferentes subconjuntos y un número diferente de variables categóricas.

Por ejemplo,

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

donde categoricalData tiene 5 niveles.

Y entonces

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

donde categoricalData.subset tiene 3 niveles.

Sin embargo, un nivel particular que está en ambos conjuntos terminará con un color diferente, lo que hace que sea más difícil leer los gráficos juntos.

¿Necesito crear un vector de colores en el dataframe? ¿O hay otra forma de asignar colores específicos a las categorías?

Para situaciones simples como el ejemplo exacto en el OP, estoy de acuerdo en que la respuesta de Thierry es la mejor. Sin embargo, creo que es útil señalar otro enfoque que se vuelve más fácil cuando intenta mantener esquemas de color consistentes en múltiples marcos de datos que no se obtienen subconjuntos de un único dataframe grande. Administrar los niveles de factores en múltiples marcos de datos puede volverse tedioso si se extraen de archivos separados y no todos los niveles de factores aparecen en cada archivo.

Una forma de abordar esto es crear una escala de color manual personalizada de la siguiente manera:

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

y luego agregue la escala de colores en la gráfica según sea necesario:

 #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 primera ttwig se ve así:

enter image description here

y el segundo argumento se ve así:

enter image description here

De esta forma, no necesita recordar o verificar cada dataframe para ver si tienen los niveles adecuados.

Estoy en la misma situación señalada por malcook en su comentario : lamentablemente, la respuesta de Thierry no funciona con la versión 0.9.3.1 de ggplot2.

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

Aquí está la primera figura:

ggplot A-E, colores mezclados

y la segunda figura:

ggplot ADE, colores mezclados

Como podemos ver, los colores no permanecen fijos, por ejemplo, E cambia de magenta a blu.

Como sugiere malcook en su comentario y por hadley en su comentario, el código que usa los limits funciona correctamente:

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

da la siguiente figura, que es correcta:

ggplot correcto

Este es el resultado 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 solución más fácil es convertir su variable categórica en un factor antes de la subconjunto. En resumen, necesita una variable de factor con exactamente los mismos niveles en todos sus subconjuntos.

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

Con una variable de caracteres

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

Con una variable de factor

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

En base a la respuesta muy útil de joran, pude encontrar esta solución para una escala de color estable para un factor booleano ( 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 

Como ColorBrewer no es muy útil con escalas de color binarias, los dos colores necesarios se definen manualmente.

Aquí myboolean es el nombre de la columna en myDataFrame contiene el factor VERDADERO / FALSO. date y duration son los nombres de las columnas que se asignarán a los ejes x e y de la gráfica en este ejemplo.

Esta es una publicación anterior, pero estaba buscando una respuesta a esta misma pregunta,

Por qué no probar algo como:

 scale_color_manual(values = c("foo" = "#999999", "bar" = "#E69F00")) 

Si tiene valores categóricos, no veo una razón por la cual esto no debería funcionar.