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:
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?
Es posible si usted tiene una lista de región y una lista de color. ¿Dónde está la lista de color? – kohske
¡Er, um, todavía no he definido uno! Una lista de colores arbitrarios sería suficiente para un ejemplo. – SlowLearner