2010-09-27 19 views
14

Ci scusiamo per i dati di esempio non inclusi per il mio problema. Non sono riuscito a trovare un modo per produrre facilmente un file di esempio. Si spera che gli utenti esperti di ggplot possano vedere cosa mi piacerebbe fare dalla descrizione seguente.Diverse legende e colori di riempimento per il ggplot sfaccettato?

ho:

  • Un data.frame X con le informazioni su aree di saggio (plotid, var1, var2, var3, var4, ...)

  • Un poligono shapefile Y con informazioni spaziali per i grafici di esempio

L'importazione dello shapefile Y (con maptools) e fortify come data.frameZ (ggplot2) funziona correttamente. melt ing X a X_melted funziona ugualmente bene. merge -ing Z e X_melted a mapdf funziona pure.

Ciò significa che ora abbiamo un data.frame in forma lungo con informazioni spaziali e var1, var2, var3, ...

Ora voglio tracciare questa cornice di dati in questo modo:

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 

Il risultato è una bella trama con un pannello per ogni variabile. Le mappe dei pannelli sono identiche, ma il colore di riempimento varia con i valori delle variabili. Fino ad ora, tutto funziona come un fascino ... con un problema:

Le variabili hanno valori min e max diversi. Ad esempio var1 va da 0 a 5, var2 da 0 a 400, var3 da 5 a 10, ecc In questo esempio, la legenda per il colore di riempimento va dal 0 a 400. var2 è ben disegnato, ma var1 e var3 sono fondamentalmente nello stesso colore.

C'è un modo per utilizzare una legenda diversa per ciascun pannello del facet? O semplicemente non è (ancora) possibile con facet_wrap o facet_grid in ggplot?

Potrei creare singoli grafici per ogni variabile e unirli a viewport, ma ci sono un sacco di variabili e questo sarebbe molto lavoro.

Oppure c'è forse un altro pacchetto o metodo che potrei usare per realizzare ciò che mi piacerebbe fare?

E l'aiuto sarebbe molto apprezzato.:)

Edit: Con l'aiuto della descrizione ggplot2 -package, ho costruito un esempio che illustra il mio 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 

Il pannello a destra mostra valori diversi per var2 sulla mappa. Tuttavia, sul pannello a sinistra, tutti i poligoni hanno lo stesso colore. Questo è logico, perché per tutti i pannelli viene utilizzata una sola sfumatura di colore. Posso usare una sfumatura di colore diversa per ciascun pannello?

risposta

13

Attualmente può essere presente una sola scala per tracciato (per tutto tranne xey).

+1

Ok, grazie per la risposta. Questa funzionalità potrebbe essere implementata in qualsiasi momento presto? ;) – donodarazao

+1

È estremamente improbabile, perché è facile lavorare aggirando trame separate. – hadley

1

Forse un po 'poco ortodosso, ma potresti provare a considerare il tuo "valore". Ad esempio:

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 utilizza fattori per creare legende. Quindi, se si potesse aggiungere una colonna che prendesse "valore" e la suddividesse in intervalli fattoriali, si potrebbe sostituire "valore" con gli intervalli.

Creare una colonna, come "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 

...

Quindi utilizzare:

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

che avrebbe dovuto indicare le categorie che si desidera, che potrebbe essere che richiede tempo. Ma almeno il grafico sarebbe venuto fuori come lo vuoi. Fondamentalmente, dovresti ricodificare i dati in un'altra colonna. Ecco alcuni esempi:

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

+0

Grazie per la risposta. Impostare lo spazio e le scale libere non aiuta, perché cambia solo l'asse x e y, ma non il codice colore. Ho modificato la mia domanda, che ora ha un esempio. – donodarazao

+0

Risposta aggiornata con aggiornamento della domanda. HTH! –

+0

E, non credo che sia possibile avere più di una leggenda in un facet_grid. –

1

A rischio di affermare l'ovvio, sembra che si dovrebbe essere colorazione da percentuali invece di valori grezzi. Quindi i valori trasformati e la tua legenda vanno da 0 a 1.

+1

L'utilizzo delle percentuali potrebbe essere una soluzione, ma alcune informazioni andrebbero ovviamente perse. Immaginate ad esempio var1 = temperatura (da 15 a 20 gradi) e var2 = rel. umidità (che varia dal 50 all'80%). I valori percentuali non sarebbero molto chiari per la temperatura e abbastanza confusionari per rel. umidità (percentuale del percento). ;) – donodarazao

3

con griglia bontà

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, posso fare uso di questo. –

+0

Hmmm, ho appena notato che per quella soluzione avresti ancora bisogno di un grafico separato per ogni variabile. Forse questo potrebbe essere realizzato con un ciclo.Qualche idea se reticolo o base potrebbero realizzare ciò che voglio senza loop? – donodarazao

+0

Sembra essere obsoleto –

Problemi correlati