Schoenere Karten mit R und ggplot2

Vor einiger Zeit hatte ich hier schon einmal beschrieben, wie sich mit R einfache Karten und Visualisierungen herstellen lassen. Das geht natuerlich noch deutlich komplexer — aber eben auch schoener. Edward Tufte sollte eigentlich allen ein Begriff sein, die sich mit Visualisierung und grafischer Aufbereitung von Information beschaeftigen; „The Visual Display of Quantitative Information“ empfehle ich immer wieder gerne (Amazon-Affilliate-Link; alternativ ISBN 0961392142).

Neben Tufte gibt es noch ein weiteres grosses Werk, auf das ich bei der ganzen Kartiererei in R gestossen bin: „The Grammar of Graphics“ (Amazon-Affilliate-Link, alternativ ISBN 0387245448). „Gestossen“ ist hier weit ausgelegt, ich habe das Buch nicht einmal gelesen. Ich kenne aber die auf ihm basierende R-Library ggplot2, die die Grammar of Graphics fuer ihre Plots verwendet — und sie dabei aesthetisch ansehlich werden laesst.

Ich verwende im folgenden Beispiel wieder das ESRI-Shapefile der Stadt mit den integrierten Altersquotienten pro Stadtviertel. Prinzipiell laesst sich hier noch viel mehr machen, naemlich auch mit Daten aus Drittquellen. Dazu komme ich in einem spaeteren Post.

Zuerst holen wir uns einige Bibliotheken, setzen das Arbeitsverzeichnis und lesen das Shapefile ein. Ich binde in diesem Tutorial die Libraries immer erst dann ein, wenn eine ihrer Funktionen zum Einsatz kommt. Ich hoffe, so ist halbwegs nachzuvollziehen, was wozu gehoert. Die rgdal-Library erfordert PROJ.4, das einige Zeit lang in Debian und seinen Derivaten in einer kaputten Version daher kam; unter Ubuntu lohnt hier ein Blick auf UbuntuGIS.

library(sp)
library(rgdal)
setwd("/media/home/opendata/altersquotient")
ulm <- readOGR(".", "G_Altersquotient_311210")

Mit einem Blick in die ersten Zeilen des Datenteils unseres Shapefiles faellt auf, dass die Codierung (wieder) etwas gelitten hat. Das laesst sich durch Konvertierung und Ueberschreiben der urspruenglichen Spalten beheben.

head(ulm@data)
ulm@data$STT_Name <- iconv(ulm@data$STT_Name, "ISO_8859-1", "UTF-8")
ulm@data$STTV_Name <- iconv(ulm@data$STTV_Name, "ISO_8859-1", "UTF-8")

Im Folgenden trennen wir den Datenteil vom eigentlichen Shape und wandeln letzteres in Koordinatenreihen um. Um hinterher die einzelnen Teile wieder sinnvoll zusammenfuehren zu koennen, verpassen wir dem ulm-Objekt eine Spalte id, die einfach der Zeilennummer entspricht. Anschliessend speichern wir den Datenteil von ulm nach ulm.df

ulm@data$id <- rownames(ulm@data)
ulm.df <- as.data.frame(ulm)

Die bekannte Library maptools hilft uns nun mit seiner fortify()-Methode, aus dem Shapefile Koordinatenreihen zu machen. Leider ist das nicht so ganz GNU-konform, so dass wir erst einmal mit gpclibPermit() die Erlaubnis geben muessen, diese Teilfunktion auch zu benutzen. (Danke an diese Tutorials und Beispiele, die mich auf die Sache mit dem fortify() gebracht haben)

library(maptools)
gpclibPermit()
ulm_fort <- fortify(ulm, region="id")

Nun muessen ulm.df und ulm_fort wieder zu einem gemeinsamen Data Frame kombiniert werden. Das uebernimmt die join()-Funktion aus der plyr-Library, die wie ein SQL-Join funktioniert. Bei komplexeren Verknuepfungen sollte man das im Kopf behalten und gegebenenfalls explizit einen left oder right oder inner join machen, um nicht zu verzweifeln 😉

Wichtig ist natuerlich, dass beide Teile eine gemeinsame Spalte haben, anhand derer sie verbunden werden koennen. Mit einem head() sehen wir, dass das wunderbar der Fall ist.

library(plyr)
head(ulm.df)
head(ulm_fort)

ulm_merged <- join(ulm_fort, ulm.df, by=“id“)

Nun wird geplottet — mit dem altbekannten RColorBrewer und der ggplot2-Library. Wir fuegen hinzu:

  • Eine Aesthetikangabe: Welche Werte sollen fuer x, y und die Fuellung der Flaechen verwendet werden? Wir faerben anhand des Altersquotienten ein.
  • Die Angabe, aus den Koordinatenreihen Polygone zu zeichnen
  • Zusaetzlich weisse Umrisse um die Stadtviertel
  • Eine Farbskala fuer die Altersquotientenfuellung. colours = brewer.pal(9,“Greens“) wuerde schon reichen, dann gaebe es aber nur fuenf Abstufungen. Stattdessen definieren wir die breaks in Zehnerabstaenden, indem wir einen geeigneten Vektor uebergeben.

library(ggplot2)
library(RColorBrewer)
ggplot(ulm_merged) +
aes(long, lat, group=group, fill=ALTQU) +
geom_polygon() +
geom_path (color="white") +
scale_fill_gradientn(colours = brewer.pal(9, "Greens"), breaks = c(10, 20, 30, 40, 50, 60, 70, 80, 90)) +
coord_equal()

Et voila — eine wunderbare Karte mit schoenem, unaufdringlichem Gitternetz und abgesetztem Hintergrund 🙂

R ist jedoch nicht „nur“ dazu da, bunte Karten zu plotten, zumal ohne raeumlichen Bezug und (in diesem Fall) im Gauss-Krueger-Koordinatensystem. Die hier verwendeten Libraries koennen jedoch noch viel mehr: Komplexe Kombinationen von Daten, und vor allem auch die Ausgabe in verschiedensten Formaten. Google Fusion Tables? GeoJSON? Kein Problem.

Mehr dazu irgendwann demnaechst 😉

4 Gedanken zu „Schoenere Karten mit R und ggplot2

    1. stk Beitragsautor

      Kein Ding. Ich ueberleg gerade, am Freitag zum OpenData-Stammtisch nach Muenchen zu fahren; momentan fehlt’s aber noch an Leuten, mit denen ich mir das Bayernticket teilen koennte.

      Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert