2017-05-23 3 views
8

Ich möchte SpatialPolygons aus Bibliothek sp mit Löchern in ggplot2 zeichnen. Dank andere Fragen auf Stackoverflow, weiß ich, dass dies erlaubt ist, während sie mit dem Uhrzeigersinn geschrieben Polygonen zu tun:
http://stackoverflow.com/questions/12047643/geom-polygon-with-multiple-hole/12051278#12051278
der Tat, wenn ein SpatialPolygons mit broom::tidy (ersetzt ggplot2::fortify) Transformieren, Löcher Polygone im Uhrzeigersinn gespeichert wie gezeichnet wird Löcher.
In ggplot2 wird die Art, wie Polygone mit Löchern gezeichnet werden, einmal mit fill und einmal mit colour gezeichnet, andernfalls können Sie Linien sehen, die Polygone kreuzen. Wenn es sich um mehrere Subpolygone handelt, einige mit Löchern, ist das schwieriger, die Reihenfolge der Punkte-Features, wie sie in broom::tidy definiert sind, erlaubt möglicherweise keine Füllung von Polygonen (siehe Bild unten).
Hat jemand von Ihnen eine Lösung, um dieses Füllproblem zu beseitigen?Zeichnen Sie SpatialPolygons mit mehreren Subpolygonen und Löchern mit ggplot2

Hier ist ein reproduzierbares Beispiel:

library(sp) 
library(ggplot2) 

# Create two polygons: second would be a hole inside the first 
xy = cbind(
    x = c(13.4, 13.4, 13.6, 13.6, 13.4), 
    y = c(48.9, 49, 49, 48.9, 48.9) 
    ) 
hole.xy <- cbind(
    x = c(13.5, 13.5, 13.45, 13.45, 13.5), 
    y = c(48.98, 48.92, 48.92, 48.98, 48.98) 
) 

# Transform as SpatialPolygons with holes 
xy.sp <- SpatialPolygons(list(
    Polygons(list(Polygon(xy), 
       Polygon(hole.xy, hole = TRUE)), "1"), 
    Polygons(list(Polygon(xy + 0.2), 
       Polygon(xy + 0.35), 
       Polygon(hole.xy + 0.2, hole = TRUE)), "2") 
)) 

# Transform SpatialObject to be used by ggplot2 
xy.sp.l <- broom::tidy(xy.sp) 

ggplot(xy.sp.l) + 
    geom_polygon(aes(x = long, y = lat, group = id, fill = id)) 

ggplot fill problem with SpatialPolygons with holes

+0

Eine Lösung würde bedeuten, die Polygone im SpatialPolygons Funktionsaufruf zu trennen. z.B. Zwei Polygone mit id = 2 werden 2a & 2b. Ist dies eine Möglichkeit oder suchen Sie nach einer Lösung ab xy.sp.l? –

Antwort

9

Könnte eine gute Zeit sein, "zu gehen", um das sf Paket. Arbeiten mit sf Objekt ist in der Tat viel einfacher in ggplot dank der geom_sf Geometrie:

library("sf") 
library("rgeos") 
sf_poly <- as(xy.sp, "sf") 
sf::st_crs(sf_poly) <- 4326 
sf_poly$id <- c(1,2) 
ggplot(sf_poly) + 
    geom_sf(aes(fill = as.factor(id))) 

enter image description here

+0

Ja tatsächlich. Ihre Antwort löst das hier gestellte Problem auf einfache Weise. Ich schätze, das wird Leute ermutigen, dieses Problem auf sf zu migrieren ... Ich warte persönlich auf den Moment, als 'sf' stabil genug war mit Parametern und Funktionsnamen. Dies führt jedoch zu meinem anderen Problem, schraffierte Flächenpolygone mit sf-Merkmalen zeichnen zu können. Ich werde meine Funktion ändern müssen, um dies mit sf und dann mit sf Flugblatt zu ermöglichen. Aber das ist eine andere Frage, für ein anderes Mal ... Danke. –

+0

Ich akzeptiere diese Antwort, um Leute dazu zu bringen, sich auf 'sf' zu bewegen.Aber die zweite Antwort wird vergeben, weil dies die Antwort auf meine Frage ist. –

1

Hinzufügen von Linien zeigt die Ursache des Problems. Das blaue "Polygon" wird gezeichnet, unteres -> oberes -> Loch.

enter image description here

Dieser Code (das ist nicht sehr elegant, leider ist) macht den Weg, bevor Sie fortfahren zu 3. bis zum Ausgangspunkt des ersten Teils zurück.

library(dplyr) 
    extra <- xy.sp.l %>% 
     filter(piece != 1) %>% 
     group_by(id, group) %>% 
     summarise(last_pt = max(order)) 


for (n in 1:nrow(extra)) { 
    id_ex <- as.character(extra[n,"id"]) 
    x <- subset(xy.sp.l, id == id_ex & piece == 1 & order == 1) 
    x$order <- as.numeric(extra[n,"last_pt"]) + 0.5 
    xy.sp.l <- rbind(xy.sp.l,x) 
} 

xy.sp.l <- xy.sp.l[order(xy.sp.l$id, xy.sp.l$order),] 

enter image description here

+0

Danke für Ihre Antwort. Ein Zurückgehen zu einem Punkt des ersten Polygons scheint das Problem für jede neue Unterpolygon- oder Polygonordnung zu lösen. Ich denke, dieser Trick kann für beliebige Polygone der Bibliothek 'sp' verwendet werden, die in' ggplot2' geplottet werden. –

+0

Ich glaube, es würde, da es das Problem der zusätzlichen Polygone (wie das obige Dreieck) erstellt wird. –

+0

Ich gebe diese Antwort, weil sie meine Frage direkt beantwortet. Um jedoch Menschen zu ermutigen, zu "sf" zu gehen, akzeptiere ich die erste Antwort. –

1

Dieser Beitrag ist eine gute Frage und erhielt bereits große Antworten. Ich glaube auch, dass Leute lernen sollten, mit sf Objekten zu arbeiten, da es die nächste Generation des räumlichen Datentyps in R ist. Aber ich möchte teilen, dass in diesem Fall geom_spatial aus dem ggspatial Paket eine Option sein könnte, die SpatialPolygons zu plotten.

library(sp) 
library(ggplot2) 
library(ggspatial) 

ggplot() + 
    geom_spatial(xy.sp, aes(fill = id)) 
# Ignoring argument 'mapping' in geom_spatial.SpatialPolygons 
# Autodetect projection: assuming lat/lon (epsg 4326) 

enter image description here

Verwandte Themen