2012-07-16 17 views
10

Me gustaría trazar algunos elementos de datos diferentes usando ggplot2, usando dos escalas de colores diferentes (una continua y una discreta de dos df diferentes). Puedo trazar exactamente cómo me gustaría individualmente, pero no puedo hacer que funcionen juntos. Parece que no puedes tener dos escalas de color diferentes operando en la misma parcela. He visto preguntas similares here y here, y esto me llevó a creer que lo que me gustaría lograr simplemente no es posible en ggplot2, pero por si me equivoco me gustaría ilustrar mi problema para ver si hay algún problema. trabajo-alrededor.Trazar escalas discretas y continuas en el mismo ggplot

Tengo algunos datos de la secuencia de GIS que tiene algunos atributos categóricos que se le atribuye, que puedo parcela (p1 en código de abajo) para obtener: enter image description here

también tengo un conjunto de ubicaciones que tienen una respuesta continua , que también puedo trazar (p2 en el código a continuación) para obtener: enter image description here Sin embargo, no puedo combinar los dos (p3 en el código a continuación). Me sale este error

Error in scales[[prev_aes]] : attempt to select less than one element

comentando la línea scale_colour_hue("Strahler order") + cambia el error de

Error: Discrete value supplied to continuous scale

Básicamente parece que ggplot2 utiliza el mismo tipo de escala (continua o discreta) para la llamada geom_path y los geom_point llamadas . Entonces cuando paso la variable discreta, factor(Strahler), a la escala scale_colour_gradientn, la trama falla.

¿Hay alguna forma de evitar esto? Sería increíble si hubiera un argumento data en una función de escalas para decirle dónde debe estar mapeando o configurando atributos. ¿Esto es posible?

Muchas gracias y reproducible código a continuación:

library(ggplot2) 

### Download df's ### 
oldwd <- getwd(); tmp <- tempdir(); setwd(tmp) 
url <- "http://dl.dropbox.com/u/44829974/Data.zip" 
f <- paste(tmp,"\\tmp.zip",sep="") 
download.file(url,f) 
unzip(f) 


### Read in data ### 
riv_df <- read.table("riv_df.csv", sep=",",h=T) 
afr_df <- read.table("afr_df.csv", sep=",",h=T) 
vil_df <- read.table("vil_df.csv", sep=",",h=T) 


### Min and max for plot area ### 
xmin <- -18; xmax <- 3; ymin <- 4; ymax <- 15 


### Plot river data ### 
p1 <- ggplot(riv_df, aes(long, lat)) + 
    geom_map(mapping = aes(long , lat , map_id = id) , fill = "white" , data = afr_df , map = afr_df) + 
    geom_path(colour = "grey95" , mapping = aes(long , lat , group = group , size = 1) , data = afr_df) + 
    geom_path(aes(group = id , alpha = I(Strahler/6) , colour = factor(Strahler) , size = Strahler/6)) + 
    scale_alpha(guide = "none") + 
    scale_colour_hue("Strahler order") + 
    scale_x_continuous(limits = c(xmin , xmax) , expand = c(0 , 0)) + 
    scale_y_continuous(limits = c(ymin , ymax) , expand = c(0 , 0)) + 
    coord_map() 
print(p1) # This may take a little while depending on computer speed... 



### Plot response data ### 
p2 <- ggplot(NULL) + 
    geom_point(aes(X , Y , colour = Z) , size = 2 , shape = 19 , data = vil_df) + 
    scale_colour_gradientn(colours = rev(heat.colors(25)) , guide="colourbar") + 
    coord_equal() 
print(p2) 



### Plot both together ### 
p3 <- ggplot(riv_df, aes(long, lat)) + 
    geom_map(mapping = aes(long , lat , map_id = id) , fill = "white" , data = afr_df , map = afr_df) + 
    geom_path(colour = "grey95" , mapping = aes(long , lat , group = group , size = 1) , data = afr_df) + 
    geom_path(aes(group = id , alpha = I(Strahler/6) , colour = factor(Strahler) , size = Strahler/6)) + 
    scale_colour_hue("Strahler order") + 
    scale_alpha(guide = "none") + 
    scale_x_continuous(limits = c(xmin , xmax) , expand = c(0 , 0)) + 
    scale_y_continuous(limits = c(ymin , ymax) , expand = c(0 , 0)) + 
    geom_point(aes(X , Y , colour = Z) , size = 2 , shape = 19 , data = vil_df) + 
    scale_colour_gradientn(colours = rev(heat.colors(25)) , guide="colourbar") + 
    coord_map() 
print(p3) 
#Error in scales[[prev_aes]] : attempt to select less than one element 

### Clear-up downloaded files ### 
unlink(tmp,recursive=T) 
setwd(oldwd) 

Cheers,

Simon

+1

El problema no es tan complicado como puedes pensar En general, solo puede asignar una estética una vez. Por lo tanto, llamar 'scale_colour_ *' dos veces no tiene sentido para ** ggplot2 **. Intentará forzar uno en el otro. – joran

+0

@joran Entonces, ¿actualmente no hay forma de asignar una estética de un color desde un marco de datos a una escala continua y otra estética de color desde un marco de datos diferente a una escala discreta? Sería útil, ¿no es así, si fuera posible especificar datos a escalas? –

+1

No puede tener varias escalas de color en el mismo gráfico, independientemente de si una es continua o discreta. El autor del paquete ha dicho que tampoco tienen intención de agregar esto. Es bastante complicado de implementar y haría demasiado fácil hacer gráficos increíblemente confusos. (Múltiples ejes y nunca se implementarán por razones similares.) – joran

Respuesta

9

Puede hacerlo. Necesitas decirle a los gráficos de la cuadrícula que superpongan una parcela encima de la otra. Usted tiene para obtener los márgenes y espaciado, etc., exactamente, y debe pensar en la transparencia de las capas superiores. En resumen ... no vale la pena. Además de hacer que la trama sea confusa.

Sin embargo, pensé que a algunas personas les gustaría un puntero sobre cómo lograr esto. nótese bienSolía ​​code from this gist para que los elementos de la trama superior transparente para que no opaca los elementos siguientes:

grid.newpage() 
pushViewport(viewport(layout = grid.layout(1 , 1 , widths = unit(1 , "npc")))) 
print(p1 + theme(legend.position="none") , vp = viewport(layout.pos.row = 1 , layout.pos.col = 1)) 
print(p2 + theme(legend.position="none") , vp = viewport(layout.pos.row = 1 , layout.pos.col = 1)) 

Véase mi respuesta here para ver cómo agregar leyendas a otra posición en el diseño de cuadrícula.

enter image description here

5

El problema no es tan complicado como parece. En general, solo puede asignar una estética una vez. Por lo tanto, llamar a scale_colour_* dos veces no tiene sentido para ggplot2. Intentará forzar uno en el otro.

No puede tener varias escalas de color en el mismo gráfico, independientemente de si una es continua o discreta. El autor del paquete ha dicho que tampoco tienen intención de agregar esto. Es bastante complicado de implementar y haría demasiado fácil hacer gráficos increíblemente confusos. (Múltiples ejes y nunca se implementarán por razones similares.)

1

que no tienen el tiempo en el momento de proporcionar un ejemplo de trabajo completa, pero no hay otra manera de hacer esto que merece ser mencionado aquí: Fill and border colour in geom_point (scale_colour_manual) in ggplot

Básicamente, utilizando geom_point en La conjunción con shape = 21, color = NA le permite controlar el color de una serie de puntos usando la estética fill en lugar de color. Esto es lo que mi código parecía para esto. Yo entiendo que no hay datos proporcionados, pero es de esperar que le proporciona un punto de partida:

biloxi + 
    geom_point(data = filter(train, primary != 'na'), 
      aes(y = GEO_LATITUDE, x = GEO_LONGITUDE, fill = primary), 
      shape = 21, color = NA, size = 1) + 
    scale_fill_manual(values = c('dodgerblue', 'firebrick')) + 
    geom_point(data = test_map_frame, 
      aes(y = GEO_LATITUDE, x = GEO_LONGITUDE, color = var_score), 
      alpha = 1, size = 1) + 
    scale_color_gradient2(low = 'dodgerblue4', high = 'firebrick4', mid = 'white', 
        midpoint = mean(test_map_frame$var_score)) 

Observe cómo cada llamada a geom_point invoca una estética diferente (color o fill)

Cuestiones relacionadas