2010-09-27 21 views
14

Disculpe por no haber incluido ningún dato de ejemplo para mi problema. No pude encontrar una manera de producir fácilmente un archivo de forma de ejemplo. Afortunadamente, los usuarios con experiencia de ggplot pueden ver lo que me gustaría hacer de la siguiente descripción.Diferentes leyendas y colores de relleno para ggplot facetado?

Tengo:

  • Un data.frame X con la información sobre parcelas de muestreo (plotid, var1, var2, var3, var4, ...)

  • Un archivo de forma poligonal Y con la información espacial para los gráficos de muestra

Importación del shapefile Y (con maptools) y fortify ing como data.frameZ (ggplot2) funciona bien. melt ing X a X_melted funciona igual de bien. merge -ing Z y X_melted a mapdf funciona también.

Eso significa que ahora tenemos un data.frame en forma de largo con información espacial y var1, var2, var3, ...

Ahora quiero graficar esta trama de datos como esto:

pl1 <- ggplot(mapdf,aes(long,lat),group=group) 
pl1 <- pl1 + geom_polygon(aes(group=group,fill=value),colour="black") 
pl1 <- pl1 + facet_grid(variable ~ .) 
pl1 <- pl1 + coord_equal(ratio = 1) 
pl1 

El resultado es una buena trama con un panel para cada variable. Los mapas de los paneles son idénticos, pero el color de relleno varía con los valores de las variables. Hasta ahora, todo funciona como un encanto ... con un problema:

Las variables tienen diferentes valores mínimos y máximos. Por ejemplo var1 va 0-5, var2 de 0 a 400, var35-10, etc. En ese ejemplo, la leyenda para el color de relleno va desde 0 a 400. var2 está muy bien dibujado, pero var1 y var3 son básicamente del mismo color.

¿Hay alguna manera de que pueda usar una leyenda diferente para cada panel de la faceta? ¿O esto simplemente no (todavía) es posible con facet_wrap o facet_grid en ggplot?

Podría hacer gráficas individuales para cada variable y unirlas con ventanas gráficas, pero hay un montón de variables y esto sería mucho trabajo.

¿O tal vez haya otro paquete o método que podría utilizar para lograr lo que me gustaría hacer?

Y la ayuda sería muy apreciada.:)

Editar: Con la ayuda de la descripción ggplot2 -El paquete, que construye un ejemplo que ilustra mi problema:

ids <- factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3")) 
values <- data.frame(
id = ids, 
val1 = cumsum(runif(6, max = 0.5)), 
val2 = cumsum(runif(6, max = 50)) 
) 
positions <- data.frame(
id = rep(ids, each = 4), 
x = c(2, 1, 1.1, 2.2, 1, 0, 0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3, 
0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 0.5, 0.6, 1.3), 
y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 1, 1.5, 
2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2) 
) 

values <- melt(values) 
datapoly <- merge(values, positions, by=c("id")) 

p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black") 
p <- p + facet_wrap(~ variable) 
p 

El panel de la derecha ilustra diferentes valores para var2 en el mapa. Sin embargo, en el panel de la izquierda, todos los polígonos tienen el mismo color. Esto es lógico, porque solo se usa un degradado de color para todos los paneles. ¿Podría usar un degradado de color diferente para cada panel?

Respuesta

13

Actualmente solo puede haber una escala por parcela (para todo excepto x e y).

+1

Ok, gracias por la respuesta. ¿Esta característica se implementará pronto? ;) – donodarazao

+1

Es extremadamente improbable, porque es fácil trabajar dibujando trazados separados. – hadley

1

Tal vez un poco heterodoxo, pero podría intentar factorizar su "valor". Por ejemplo:

p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=factor(value), group=id),colour="black") 
p <- p + facet_wrap(~ variable) 
p 

ggplot2 utiliza factores para crear leyendas. Entonces, si pudiera agregar una columna que tomara "valor" y la dividiera en rangos factorizados, podría reemplazar "valor" con los rangos.

Crear una columna, como "f":

id variable  value x y f 
1 1.1  val1 0.09838607 2.0 -0.5 0.09-0.13 
2 1.1  val1 0.09838607 1.0 0.0 0.09-0.13 
3 1.1  val1 0.09838607 1.1 1.0 0.09-0.13 
4 1.1  val1 0.09838607 2.2 0.5 0.09-0.13 
25 2.1  val1 0.13121347 1.0 0.0 0.13-0.20 

...

A continuación, utilice:

p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=f, group=id),colour="black") 
p <- p + facet_wrap(~ variable) 
p 

que tendría que especificar las categorías que desee, lo cual podría tomar mucho tiempo. Pero al menos el gráfico saldría como tú quieras. Básicamente, estarías recodificando los datos en otra columna. He aquí algunos ejemplos:

http://www.statmethods.net/management/variables.html

+0

Gracias por su respuesta. Establecer el espacio y las escalas libres no ayuda, porque solo cambia el eje xyy, pero no el código de color. Edité mi pregunta, que ahora tiene un ejemplo. – donodarazao

+0

Respuesta actualizada con la actualización de la pregunta. HTH! –

+0

Y, no creo que sea posible tener más de una leyenda en facet_grid. –

1

A riesgo de afirmar lo obvio, parece que usted debe Coloración por ciento en lugar de valores en bruto. Entonces sus valores transformados y su leyenda van de 0 a 1.

+1

Usar porcentajes podría ser una solución, pero se perdería cierta información. Imagine por ejemplo var1 = temperatura (que varía de 15 a 20 grados) y var2 = rel. humedad (entre 50 y 80%). Los valores porcentuales no serían muy claros para la temperatura y bastante confusos para rel. humedad (porcentaje del porcentaje). ;) – donodarazao

3

Con la bondad rejilla

align.plots <- function(..., vertical=TRUE){ 
#http://ggextra.googlecode.com/svn/trunk/R/align.r 
    dots <- list(...) 
    dots <- lapply(dots, ggplotGrob) 
    ytitles <- lapply(dots, function(.g) editGrob(getGrob(.g,"axis.title.y.text",grep=TRUE), vp=NULL)) 
    ylabels <- lapply(dots, function(.g) editGrob(getGrob(.g,"axis.text.y.text",grep=TRUE), vp=NULL)) 
    legends <- lapply(dots, function(.g) if(!is.null(.g$children$legends)) 
        editGrob(.g$children$legends, vp=NULL) else ggplot2:::.zeroGrob) 

    gl <- grid.layout(nrow=length(dots)) 
    vp <- viewport(layout=gl) 
    pushViewport(vp) 
    widths.left <- mapply(`+`, e1=lapply(ytitles, grobWidth), 
         e2= lapply(ylabels, grobWidth), SIMPLIFY=F) 
    widths.right <- lapply(legends, function(g) grobWidth(g) + if(is.zero(g)) unit(0, "lines") else unit(0.5, "lines")) # safe margin recently added to ggplot2 
    widths.left.max <- max(do.call(unit.c, widths.left)) 
    widths.right.max <- max(do.call(unit.c, widths.right)) 

    for(ii in seq_along(dots)){ 
    pushViewport(viewport(layout.pos.row=ii)) 
    pushViewport(viewport(x=unit(0, "npc") + widths.left.max - widths.left[[ii]], 
          width=unit(1, "npc") - widths.left.max + widths.left[[ii]] - 
               widths.right.max + widths.right[[ii]], 
          just="left")) 
    grid.draw(dots[[ii]]) 
    upViewport(2) 
    } 
} 



p <- ggplot(datapoly[datapoly$variable=="val1",], aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black") 
p1 <- ggplot(datapoly[datapoly$variable=="val2",], aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black") 
align.plots(p,p1) 
+0

+1, puedo hacer uso de esto. –

+0

Hmmm, acabo de notar que para esa solución, aún necesitaría un diagrama separado para cada variable. Quizás esto podría lograrse con un bucle.¿Alguna idea de si el enrejado o la base podría lograr lo que quiero sin bucles? – donodarazao

+0

Parece estar desactualizado –

Cuestiones relacionadas