2010-09-27 11 views
14

Entschuldigung, dass keine Beispieldaten für mein Problem enthalten sind. Ich konnte keine einfache Möglichkeit finden, eine Beispielformdatei zu erstellen. Hoffentlich können erfahrene Benutzer von ggplot sehen, was ich aus der folgenden Beschreibung machen möchte.Verschiedene Legenden und Füllfarben für facettierten ggplot?

Ich habe:

  • A data.frame X mit Informationen über Probeflächen (plotid, var1, var2, var3, var4, ...)

  • Eine Polygon Shape-Datei Y mit räumlichen Informationen für die Probeplots

Import des Shapefiles Y (mit maptools) und fortify ing als data.frameZ (ggplot2) funktioniert gut. melt ing X bis X_melted funktioniert genauso gut. merge -ing Z und X_melted zu mapdf funktioniert auch.

Das bedeutet, dass wir jetzt eine data.frame in Langform mit räumlichen Informationen haben und var1, var2, var3, ...

nun wie folgt Ich möchte diesen Datenrahmen zeichnen:

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 

Das Ergebnis ist ein nettes Diagramm mit einem Panel für jede Variable. Die Karten der Panels sind identisch, aber die Füllfarbe variiert mit den Werten der Variablen. Bis jetzt funktioniert alles wie ein Zauber ... mit einem Problem:

Die Variablen haben unterschiedliche Min- und Max-Werte. Zum Beispiel var1 geht 0-5, var2 von 0 zu 400, var35-10 usw. In diesem Beispiel ist die Legende für die Füllfarbe von 0 zu 400 geht. var2 ist schön gezeichnet, aber var1 und var3 sind grundsätzlich in der gleichen Farbe.

Gibt es eine Möglichkeit, eine andere Legende für jedes Facettenfeld zu verwenden? Oder ist das einfach (noch) nicht möglich mit facet_wrap oder facet_grid in ggplot?

Ich könnte einzelne Diagramme für jede Variable erstellen und sie mit Ansichtsfenstern verbinden, aber es gibt eine Vielzahl von Variablen und das wäre eine Menge Arbeit.

Oder gibt es vielleicht ein anderes Paket oder eine Methode, die ich verwenden könnte, um das zu erreichen, was ich tun möchte?

Und Hilfe würde sehr geschätzt werden.:)

Edit: Mit Hilfe der ggplot2 -package Beschreibung konstruierte ich ein Beispiel, das mein Problem veranschaulicht:

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 

Das Panel auf der rechten Seite zeigt verschiedene Werte für var2 auf der Karte. Auf der linken Seite haben alle Polygone die gleiche Farbe. Dies ist logisch, da für alle Panels nur ein Farbverlauf verwendet wird. Könnte ich für jedes Panel einen anderen Farbverlauf verwenden?

Antwort

13

Zur Zeit kann es nur eine Skala pro Diagramm geben (für alles außer x und y).

+1

Ok, danke für die Antwort. Wird dieses Feature vielleicht bald implementiert? ;) – donodarazao

+1

Es ist extrem unwahrscheinlich, weil es einfach ist, mit separaten Plots zu arbeiten. – hadley

1

Vielleicht ein wenig unorthodox, aber Sie könnten versuchen, Ihren "Wert" zu faktorisieren. Beispiel:

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 verwendet Faktoren zum Erstellen von Legenden. Wenn Sie also eine Spalte hinzufügen könnten, die "value" enthält und sie in faktorisierte Bereiche aufteilt, könnten Sie "value" durch die Bereiche ersetzen.

Erstellen Sie eine Spalte, wie "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 

...

Dann nutzen:

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

Sie würden die Kategorien angeben, die Sie möchten, die könnte zeitaufwendig sein. Aber wenigstens würde die Grafik herauskommen, wie Sie es wollen. Im Grunde würden Sie die Daten in eine andere Spalte umkodieren. Hier sind einige Beispiele:

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

+0

Vielen Dank für Ihre Antwort. Platz und Skalen frei zu setzen hilft nicht, weil es nur X- und Y-Achse ändert, aber keine Farbkodierung. Ich habe meine Frage bearbeitet, die jetzt ein Beispiel hat. – donodarazao

+0

Antwort aktualisiert mit Fragenupdate. HTH! –

+0

Und ich glaube nicht, dass es möglich ist, mehr als eine Legende in einem facet_grid zu haben. –

1

Auf der Gefahr das Offensichtliche, es scheint, wie Sie durch Prozent statt Rohwerte Färbung werden sollen. Dann gehen Ihre transformierten Werte und Ihre Legende von 0 auf 1.

+1

Prozent verwenden könnte eine Lösung sein, aber einige Informationen würden offensichtlich verloren gehen. Stellen Sie sich zB var1 = Temperatur (von 15 bis 20 Grad) und var2 = rel vor. Luftfeuchtigkeit (von 50 bis 80%). Prozentwerte wären für die Temperatur nicht sehr klar und für rel relativ verwirrend. Feuchtigkeit (Prozent in Prozent). ;) – donodarazao

3

Mit Gitter Güte

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, ich kann das nutzen. –

+0

Hmmm, ich habe gerade bemerkt, dass Sie für diese Lösung immer noch ein separates Diagramm für jede Variable benötigen. Vielleicht könnte dies mit einer Schleife erreicht werden.Irgendwelche Ideen, wenn Gitter oder Basis das erreichen könnten, was ich ohne Schleifen will? – donodarazao

+0

Es scheint veraltet zu sein –