2012-04-22 20 views
5

Quiero colorear los fondos de un diagrama de facetas ggplot2 dependiendo del valor dado en una columna en particular. Usando respuestas a preguntas anteriores que ya he preguntado, pude armar lo que necesitaba juntos. La respuesta de @ joran a la pregunta this fue particularmente útil ya que ilustra la técnica de crear un marco de datos separado para pasar a ggplot.Especificando colores mediante programación en scale_fill_manual ggplot call

Todo esto funciona lo suficientemente bien, dando el resultado que se muestra en la siguiente imagen: facets coloured by region

Aquí está el código que utiliza para generar el gráfico de arriba:

# User-defined variables go here 

list_of_names <- c('aa','bb','cc','dd','ee','ff') 
list_of_regions <- c('europe','north america','europe','asia','asia','japan') 

# Libraries 

require(ggplot2) 
require(reshape) 

# Create random data with meaningless column names 
set.seed(123) 
myrows <- 30 
mydf <- data.frame(date = seq(as.Date('2012-01-01'), by = "day", length.out = myrows), 
        aa = runif(myrows, min=1, max=2), 
        bb = runif(myrows, min=1, max=2), 
        cc = runif(myrows, min=1, max=2), 
        dd = runif(myrows, min=1, max=2), 
        ee = runif(myrows, min=1, max=2), 
        ff = runif(myrows, min=1, max=2)) 

# Transform data frame from wide to long 

mydf <- melt(mydf, id = c('date')) 
mydf$region <- as.character("unassigned") 

# Assign regional label 

for (ii in seq_along(mydf$date)) { 
    for (jj in seq_along(list_of_names)) { 
     if(as.character(mydf[ii,2]) == list_of_names[jj]) {mydf$region[ii] <- as.character(list_of_regions[jj])} 
    } 
} 

# Create data frame to pass to ggplot for facet colours 
mysubset <- unique(mydf[,c('variable','region')]) 
mysubset$value <- median(mydf$value) # a dummy value but one within the range used in the data frame 
mysubset$date <- as.Date(mydf$date[1]) # a dummy date within the range used 

# ... And plot 
p1 <- ggplot(mydf, aes(y = value, x = date, group = variable)) + 
    geom_rect(data = mysubset, aes(fill = region), xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf, alpha = 0.3) + 
    scale_fill_manual(values = c("japan" = "red", "north america" = "green", "asia" = "orange", "europe" = "blue")) + 
    geom_line() + 
    facet_wrap(~ variable, ncol = 2) 

print (p1) 

La secuencia de comandos en el mundo real hacia que estoy trabajando está destinado a ser utilizado para muchos grupos diferentes que contienen muchas series de datos diferentes, por lo que este script se duplicará muchas veces, cambiando solo las variables.

Esto hace que sea importante tener los elementos definidos por el usuario claramente accesibles para la edición, por lo que las variables list_of_names yse colocan al principio del archivo. (Por supuesto, sería mejor no necesitar cambiar el script en absoluto, sino definir estas listas como archivos externos o pasarlas al script como argumentos.) Traté de generalizar la solución usando esos dos bucles for para asignar el regiones. Estuve jugando un rato tratando de obtener una solución más centrada en R utilizando las funciones apply, pero no pude hacerlo funcionar, así que me rendí y me quedé con lo que sabía.

Sin embargo, en mi código tal como está, la llamada scale_fill_manual necesita ser expuesta explícitamente variables para definir colores de relleno, como 'europe' = 'blue'. Estas variables variarán según los datos que estoy procesando, de modo que con el script en su forma actual, tendré que editar manualmente la parte ggplot del script para cada grupo de series de datos. Sé que tomaría mucho tiempo y sospecho fuertemente que también sería muy propenso a errores.

P. Idealmente me gustaría ser capaz de extraer y definir los valores requeridos para la scale_fill_manual llamada de una lista previamente declarado de valores (en este caso de list_of_regions) emparejado a una lista previamente declarado de colores mediante programación, pero No puedo pensar en una forma de lograr esto. ¿Tienes alguna idea?

+0

Es posible si usted tiene una lista de región y una lista de color. ¿Dónde está la lista de color? – kohske

+0

¡Er, um, todavía no he definido uno! Una lista de colores arbitrarios sería suficiente para un ejemplo. – SlowLearner

Respuesta

4

¿Le sirve de ayuda?

cols <- rainbow(nrow(mtcars)) 
mtcars$car <- rownames(mtcars) 

ggplot(mtcars, aes(mpg, disp, colour = car)) + geom_point() + 
    scale_colour_manual(limits = mtcars$car, values = cols) + 
    guides(colour = guide_legend(ncol = 3)) 

enter image description here

+0

Gracias por este @kohske. v0.90 obediente! Solo para aclarar, si quisiera especificar los colores para cada uno de los autos, ¿cómo abordaría eso? (Disculpas, dije que una lista arbitraria de colores estaría bien. Debería haber dicho que no me importa qué colores se usen, pero me gustaría poder definir el color para cada artículo, en este caso cada uno modelo de automóvil.) – SlowLearner

+0

Luego modifique los 'cols' como desee. Lo que es importante es la correspondencia de 'limits' y' values' en 'scale_colour_manual'. – kohske

+0

Suena sencillo. Entonces 'limits' especifica el artículo y' values' el color, de modo que al primer elemento de la lista 'limits' se le asigna el primer color en la lista' values', y así sucesivamente? – SlowLearner

Cuestiones relacionadas