2015-11-29 3 views
5

Ich möchte, dass ggplot in einer bestimmten Reihenfolge gezeichnet wird, um zu steuern, was sichtbar ist, wenn sich Objekte überlappen. Jede Datenreihe wird einem Verbund von 2 Geometrieebenen zugeordnet - die Einzelheiten der Darstellung erfordern dies. Ich habe eine Schleife dafür benutzt, aber es ist sehr langsam. Ich frage mich, ob es einen besseren Weg gibt? z.B.Steuerung der Plot-Reihenfolge für visuelle Objekte mit mehreren Geometrien in ggplot2

d = data.frame(x=c(1,5,2,2,4,2), y=c(1,1,4,3,3,5), grp=c(1,1,1,2,2,2)) 

ggplot(d, aes(x, y, group=grp)) + 
    geom_polygon(aes(fill = factor(grp))) + 
    geom_line(size=1) 

enter image description here

Jede Polygon Linie sollte mit seinem Polygon zeichnen - so zum Beispiel Die Linie des roten Polygons sollte durch das blaue Polygon verdeckt sein. Gibt es eine Möglichkeit, dies ohne Schleifen zu erreichen, wenn sowohl geom_polygon als auch geom_line denselben Datensatz verwenden?


Edit: Looping Methoden ..

Hier sind Loop-Methoden, die ich verwendet habe. Es wurde ein besserer Datensatz zum Vergleichen der Leistung hinzugefügt. Beide benötigen ungefähr 5,6 Sekunden, um auf meiner Maschine zu laufen. Im Vergleich dazu benötigt der typische Ansatz (ggplot(d, aes(x, y, fill=factor(grp))) + geom_polygon() + geom_line(size=1)) 0,45s.

d = data.frame(x = sample(-30:30,99,rep=T) + rep(sample(1:100,33),each=3), 
       y = sample(-30:30,99,rep=T) + rep(sample(1:100,33),each=3), 
       grp = rep(1:33,each=3)) 

# Method 1 - for loop 
p = ggplot() 
for(g in unique(d$grp)){ 
    dat = subset(d, grp == g) 
    p = p + geom_polygon(data=dat, aes(x, y, fill = factor(grp))) + 
    geom_line(data=dat, aes(x, y), size=1) 
} 
print(p) 

# Method 2 - apply 
ggplot() + lapply(unique(d$grp), FUN=function(g){ 
    dat = subset(d, grp == g) 
    list(geom_polygon(data=dat, aes(x, y, fill = factor(grp))), 
     geom_line(data=dat, aes(x, y), size=1)) 
}) 

enter image description here

+0

Ich glaube, das Problem, mit dem Sie konfrontiert sind, hat mit der Linie zu tun. Wenn Sie die geom_line() entfernen, erhalten Sie das gewünschte Ergebnis. Wenn Sie die geom_line vor dem geom_polygon() platzieren, erhalten Sie, was ich denke, ist Ihre gewünschte Ausgabe –

+1

Können Sie die for-Schleife anzeigen, die Sie verwendet haben? – Heroka

+0

@geotheory Es tut mir leid, ich habe keine Lösung. Die einzige Idee, die ich habe, ist, ein extra Polygon für jede Gruppe zu erstellen, das an den Seiten etwas größer ist, wenn Sie die Linie brauchen, und diese zuerst in Schwarz und dann in Farbe überzeichnen. Ich denke jedoch, dass dies viel mehr Zeit zum Programmieren/Testen benötigen würde, als für das Ausführen der Schleife zum Generieren Ihres Bildes. – Heroka

Antwort

1

habe ich nur den Code und verändert die Reihenfolge der Schichten in ggplot2 es so

d = data.frame(x=c(1,5,2,2,4,2), y=c(1,1,4,3,3,5), grp=c(1,1,1,2,2,2)) 

ggplot(d, aes(x, y, group=grp)) + 
    geom_line(size=1)+ 
    geom_polygon(aes(fill = factor(grp))) 

Und das Ergebnis sieht dann ist dies ein

enter image description here

Beachten Sie auch, dass wenn Sie den geom_line Aufruf entfernen, Sie das gleiche Ergebnis aber ohne den Rand erzeugen.

+0

Sorry Matian, das hilft nicht wirklich. Du zeichnest einfach alle Linien vorher (also darunter) alle Polygone. Sehen Sie, wie das blau-grüne Polygon einen Teil der Linie verloren hat. – geotheory

+0

Ich verstehe. So weit ich gerade jetzt denken kann, würde ich vorschlagen, die Linie fallen zu lassen (sie grenzt im ursprünglichen Beispiel sowieso nicht an die Dreiecke). Ich werde später einen zweiten Gedanken machen. Ich denke, dass geom_line möglicherweise nicht der beste Weg ist, es zu tun ... vielleicht geom_segment –

+0

Ja, die Zeile ist nur ein Demo-Beispiel. Meine Visualisierung benötigt 2 separate Geometrien. – geotheory

Verwandte Themen