Verschiedene Legenden und Füllfarben für facettierten ggplot?
Frage
Es tut uns keine Beispieldaten für mein Problem enthalten. Ich konnte keinen Weg finden, um leicht ein Beispiel Shape-Datei zu erzeugen. Hoffentlich erfahrene Anwender von ggplot
sehen kann, was ich möchte aus der folgenden Beschreibung tun.
Ich habe:
-
A
data.frame
X mit Informationen über Probeflächen (plotid
,var1
,var2
,var3
,var4
, ...) -
Ein Polygon Shape-Datei
Y
mit räumlichen Informationen für die Probeflächen
Die Einfuhr der Shape-Datei Y
(mit maptools
) und fortify
ing als data.frame
Z
(ggplot2
) funktioniert gut. melt
ing X
zu X_melted
funktioniert genauso gut. merge
-ing Z
und X_melted
zu mapdf
Werken auch.
Das bedeutet, dass wir nun eine data.frame
in Langform haben mit räumlichen Information und var1
, var2
, var3
, ...
Jetzt möchte ich so 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 schönes Grundstück mit einer Platte für jede Variable. Die Karten der Platten identisch sind, aber Füllfarbe ändert sich mit den Werten der Variablen. Bis jetzt alles funktioniert wie ein Zauber ... mit einem Problem:
Die Variablen haben unterschiedliche Min- und Max-Werte. Zum Beispiel var1
von 0
zu 5
geht, var2
von 0
zu 400
, var3
von 5
zu 10
usw. In diesem Beispiel geht die Legende für die Füllfarbe von 0
zu 400
. var2
ist schön gezeichnet, aber var1
und var3
ist im Grunde in der gleichen Farbe.
Gibt es eine Möglichkeit ich eine andere Legende für jede Platte der Facette verwenden könnte? Oder ist das einfach (noch) nicht möglich, mit facet_wrap
oder facet_grid
in ggplot
?
I einzelne Parzellen für jede Variable machen könnte und verbinden sie mit Ansichtsfenstern, aber es gibt eine Fülle von Variablen und das würde eine Menge Arbeit sein.
Oder gibt es vielleicht ein anderes Paket oder Methode, die ich nutzen könnte, um zu erreichen, was Ich mag würde tun?
Und Hilfe wäre sehr geschätzt. :)
Edit:
Mit Hilfe der ggplot2
-Paketbeschreibung, 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 dem Podium auf der linken Seite jedoch alle Polygone haben die gleiche Farbe. Dies ist logisch, da nur ein Farbverlauf für alle Platten verwendet wird. Könnte ich einen anderen Farbverlauf für jedes Panel verwenden?
Lösung
Zur Zeit kann es nur ein Maßstab pro Parzelle sein (für alles außer x und y).
Andere Tipps
Mit Gittern 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)
Auf der Gefahr die Offensichtliche, scheint es, wie Sie durch Prozent statt Rohwerte Färbung werden sollen. Dann ist Ihre transformierten Werte und Ihre Legende geht von 0 bis 1.
Vielleicht ein wenig unorthodox, aber man könnte versuchen Ihren „Wert“ Factoring. Zum 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 Legenden zu erstellen. Also, wenn Sie eine Spalte hinzufügen könnte, die „Wert“ und bricht es in faktorisierter Bereiche nimmt, könnte man „Wert“ mit den Bereichen ersetzen.
Erstelleneine 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 müßten die Kategorien angeben, dass Sie mögen, was zeitaufwendig sein könnte. Aber zumindest würde das Diagramm, wie Sie es wollen. Grundsätzlich würden Sie die Daten in einer anderen Spalte werden Umkodierung. Hier sind einige Beispiele: