ggplot2 Erweiterungen: Diagramme kombinieren, Kartenerstellung und interaktive Grafiken

Data Science 1 - Programmieren & Visualisieren

Saskia Otto & Monika Eberhard

Universität Hamburg, IMF

Wintersemester 2025/2026

Lernziele

Am Ende dieser VL- und Übungseinheit werden Sie

  • ggplot2 Diagramme mit dem Paket gridExtra oder cowplot kombinieren können.
  • einfache Karten mit dem ggplot2 Paket erstellen können.
  • einen Überblick über weitere, aktuell beliebte R Pakete zu statischen Karten haben.
  • interaktive Karten mit dem Paket leaflet erstellen können.
  • statische Diagramme und Karten von ggplot2 zu interaktiven plotly Grafiken konvertieren können.

Diagramme kombinieren

Übersicht an R Paketen und Funktionen

  • Für ‘ggplot’ Objekte funktionieren die Standard R Funktionen par() und layout() nicht
  • Hilfreiche Pakete und Funktionen:
    • älter & robust, eignet sich zum Mischen von ggplot2-Plots und Tabellen/Bildern/.. : gridExtragrid.arrange()
    • modern, sehr praktisch für reine ggplot2-Grafiken: patchwork
    • ‘Publikationsfertige’ ggplot2-Diagramme: cowplotplot_grid() und draw_plot()


Alle diese Funktionen verwenden intern folgende Rasterspezifikationen (in ‘npc’ Einheiten)

Demo-Diagramme

Jede Herangehensweise wird mit 3 verschiedenen Diagramme vom bshydro15 Datensatz demonstriert:

Code
summer <- bshydro15 |>
  filter(pres <= 5,  month %in% c("May", "Jun", "Jul", "Aug"))

a <- summer |>
  select(sampling_id, month) |>
  distinct()  |>
  ggplot(aes(x = month)) +
    geom_bar(aes(fill = month)) +
    guides(fill = "none") +
    scale_fill_brewer(palette = "Set1") +
    guides(x = guide_axis(angle = 90)) +
  theme_classic() 

sss_sum <-summer |>
  # Bildung des Temperaturmittelwerts über die 5m
  group_by(ices_sd, station, lat, long, date_time, month, day) |>
  summarise(psal = mean(psal, na.rm = TRUE)) |>
  ungroup() |>
  drop_na()

b <- ggplot(sss_sum, aes(x = long, y = psal, col = ices_sd)) +
  geom_point() +
  scale_colour_brewer(palette = "Paired") +
  guides(colour = "none") +
  theme_classic() 

c <- sst_sum |>
  filter(month %in% c("May", "Aug")) |>
  ggplot(aes(long,lat))+
    geom_point(aes(colour = temp)) +
    scale_colour_gradient(low = "white", high = "red") +
    facet_grid(. ~ month) +
    theme_classic() 
a

Säulendiagramm - Anzahl der Messungen pro Sommermonat

b

Streudiagramm - Beziehung zwischen Längengrad & Salzgehalt (pro Teilgebiet)

c

Streudiagramm - Räumliche Verteilung der Oberflächentemperaturen (Mai-August)

Diagramme mit ‘patchwork’ | 1

Diagramme nebeneinander anordnen mit +:

library(patchwork)
a + b + c

Diagramme mit ‘patchwork’ | 2

Diagramme untereinander anordnen mit /:

a / b / c

Diagramme mit ‘patchwork’ | 3

Klammern setzen für komplexere Aufteilungen:

(a + b) / c

Das ‘cowplot’ Paket

  • bietet ein publikationsfertiges Design für ‘ggplot2’
  • hat seine eigene, eingebaute Layoutvorlage: weißer Hintergrund ohne Raster (ähnlich zu theme_classic()), verschiedene Schriftgrößen
  • Die Funktion plot_grid() ist eine Kurzform mit limitierten Einstellungen:
library(cowplot)
plot_grid(a,b,c, labels = c("a)", "b)", "c)"), ncol = 3)

Diagramme mit ‘cowplot’

Für weitere Anpassungen (wie Anordnung und Größe) kombiniere folgende Funktionen

  1. ggdraw() → initialisiert eine leere Zeichenleinwand
  2. draw_plot() → platziert ein (Teil-)Diagramm irgendwo auf der Zeichenfläche
  3. draw_plot_label() → fügt die Beschriftungen zu den Diagrammen (voreingestellt ist die obere linke Ecke)

Diagramme mit ‘cowplot’ | Beispiel

(abc <- ggdraw() +
  draw_plot(a, x = 0, y = .5, width = .5, height = .5) +
  draw_plot(b, x = .5, y = .5, width = .5, height = .5) +
  draw_plot(c, x = 0, y = 0, width = 1, height = .5) +
  draw_plot_label(label = c("a)","b)","c)"), x = c(0,.5,0), y=c(1,1,.5), size = 15))

Verschachtelte Diagramme

  • Für das große Diagramm wird die Position auf 0 gesetzt und eine Breite und Höhe von 1 festgelegt (=default).
  • Beim kleineren Diagramm muss die Höhe und Breite entsprechend verringert (<1) und die gewünschte Position gewählt werden.
ggdraw() +
  draw_plot(b) + # Hauptdiagramm
  draw_plot(a, x = 0.4, y = 0.5, 
    width = .4, height = .4)

Speichern von ‘cowplots’

  • Zur Erinnerung: ggsave() (in ‘ggplot2’) kann verwendet werden um ‘ggplots’ als PDF- oder PNG-Datei zu speichern.
  • Eine bessere Lösung für ‘cowplots’ ist: save_plot() (in ‘cowplot’)
    • → das Raster-Layout kann spezifiziert werden, so dass das PDF optimal formatiert und skaliert ist.
save_plot("abc.pdf", abc,
  # spezifiziert das Seitenverhältnis (Breite/Höhe):
  base_asp = 1.3,
  # die Rasterspezifikation passt die Größe an:
  ncol = 2,  nrow = 2 )

Topografische vs. thematische Karten

Topografische Karten (Landkarten)

  • Dienen der Orientierung im Gelände und der Ausmessung von Standorten und anderen sichtbaren Details der Erdoberfläche.
  • Grundlage von Planungszwecke und Forschungsvorhaben.
  • Basis der meisten thematischen Karten.
  • Maßstab ist meist 1:25.000 bis 1:200.000.

Ausschnitt aus der topografischen USGS-Karte von Stowe, Vermont, USA (Maßstab 1:24.000).

Bildquelle: United States Geological Survey (CC0-Lizenz)

Thematische Karten (Kartogramme) | 1

  • Zur Darstellung bestimmter Themen und Merkmale (z.B. Bevölkerungsdichte, Artverbreitung).
  • Darstellung von Zusammenhängen thematischer Ebenen (z.B. zeitliche Änderungen von Merkmalen wie Bevölkerungsdichte).
  • Wesentliche Eigenschaften: Sachbezug, Zeitbezug, Raumbezug
  • Darstellungsmittel: Punkte, Linien und Flächen (in Kombination)

Modell von geografischen Phänomene sowie deren Visualisierungsmöglichkeiten

Flächenkartogramm, Choroplethenkarte

Durchschnittliches Vermögen pro Erwachsenem in US-Dollar im Jahr 2018, basierend auf dem Global Wealth Databook der Credit Suisse.
  • Gesammelte und typischerweise gruppierte Daten (z. B. nach Regionen) werden als Fläche durch Farben, Schattierungen oder Schraffierungen abhängig zum darzustellenden Wert abgebildet.
  • Je nach Art und Weise der Gruppierung (z. B. durch Mittelwertbildung, Median oder Summierung) kann das Ergebnis bzw. der Wert unterschiedlich sein.

Bildquelle: Wikipedia (CC-BY-SA 4.0 Lizenz)

Verhältnissymbolkarte

Punktkartogramm des gesamten Bruttoinlandsprodukts der Länder in Europa im Jahr 2018.
  • engl. ‘Proportional Symbol Map’
  • Punktsymbole unterschiedlicher Größe (Höhe, Länge, Fläche oder Volumen) werden verwendet, um quantitative statistische Werte darzustellen, die mit verschiedenen Bereichen oder Orten innerhalb der Karte verbunden sind.
  • Erfolgt die Anordnung der Punkte auf der Fläche schematisch innerhalb von (administrativen) Bezugsflächen spricht man auch von einem Punktkartogramm.

Bildquelle: Wikipedia (CC-BY-SA 4.0 Lizenz)

Punktstreukarte

  • engl. ‘Dot-Map’
  • Jeder vorhandenen Datensatz wird mit einem Symbol dargestellt.
  • Bei interpolierten Daten wird ein Mittelpunkt gebildet oder es wird an der Stelle dargestellt, wo der Wert am ehesten lokalisiert ist.
  • Ziel: Erfassung des tatsächlichen Verteilungsbilds.

Isoplethenkarte (Konturkarte)

  • Besteht aus einer Menge von interpolierten Isolinien, welche aus Stichprobenpunkten von bekannten Werten generiert werden.

Beispiel von einer Schätzung über die Zahl der einheimischen Arten pro 10.000 km2

Bildquelle: Greg J. Schmidt, Misako Nishino und John Kartes. Density Gradient Map Samples Produced From BONAP’s Floristic Synthesis

Kartenerstellung mit ggplot2 (und ggspatial)

Kartendaten abgreifen mit ‘map_data’

# Weltkarte 1 (Atlantik im Zentrum)
world <- map_data(map = 'world')

# Deutschland aus Weltkarte beim Abgreifen filtern
germany <- map_data(map = 'world', region = 'Germany')
str(germany)
'data.frame':   568 obs. of  6 variables:
 $ long     : num  14.2 14.2 14 13.9 13.9 ...
 $ lat      : num  53.9 53.9 53.9 53.9 53.9 ...
 $ group    : num  1 1 1 1 1 1 1 1 1 1 ...
 $ order    : int  1 2 3 4 5 6 7 8 9 10 ...
 $ region   : chr  "Germany" "Germany" "Germany" "Germany" ...
 $ subregion: chr  "Usedom" "Usedom" "Usedom" "Usedom" ...

Weltkarte erstellen

geom_polygon()

wmap <- ggplot(world, aes(x = long, y = lat)) +
  geom_polygon(aes(group = group, fill = region)) +
  guides(fill = 'none')  +  scale_fill_grey()  +  theme_minimal()
wmap

Städte als Punkte in Karte einzeichnen

+ geom_point()

data(world.cities, package = 'maps')
capitals <- filter(world.cities, capital == 1)
wmap + 
  geom_point(data = capitals, colour = 'dodgerblue4')

Umrisskarte erstellen

+ annotation_borders()

# Grundplot (Streudiagramm mit Hauptstädten)
ggplot(capitals, aes(x = long, y = lat)) +
  annotation_borders() +
  geom_point() 

Koordinatensystem fixieren

+ coord_fixed(ratio = 1.3)

Nach Europa zoomen mit xlim,ylim
wmap + 
  coord_fixed(ratio = 1.3, 
    xlim = c(-10, 30), ylim = c(35,70)) 

Kartenprojektion | 1

+ coord_map()

Standardprojektion ist 'Mercator'
# ?coord_map

wmap + 
  coord_map(
    projection = 'mercator', # default
    xlim = c(-10, 30), ylim = c(35,70)
  )

Kartenprojektion | 2

Eine recht ansprechende Projektion ist die orthografische Azimutalprojektion welche den Nordpol im Zentrum hat:

projection = 'orthographic'
# Das Zentrum muss in die Mitte des 
# Zoomausschnitts verschoben werden:
# 'orientiation' = c(latitute, 
#             longitude, rotation)
wmap + 
  coord_map(
    projection = 'orthographic', 
    orientation = c(55, 10,0),
    xlim = c(-10, 30), ylim = c(35,70)
  )

Anfügen weiterer Daten

Beispiel für eine Choroplethenkarte

Code
wooded_area <- read.csv("area_of_wooded_land.csv", sep = ";")
# Einfügen der neuen Daten in 'world' data frame
world_wood <- dplyr::left_join(world, wooded_area, by = c("region" = "country"))

# Darstellung der Europakarte mit neuen Daten
wood_map <- ggplot(world_wood, aes(x = long, y = lat)) +
  geom_polygon(aes(group = group, fill = X2020)) + # fill = X2020 ist neu
  # Anpassung der kontinuerlichen Farbskala und Legende
  scale_fill_gradient2(low = "#edf8e9", mid = "#74c476", high = "#005a32",
    midpoint = 10000, guide = "legend", n.breaks = 10) +
  labs(x = "Längengrad", y = "Breitengrad",
    fill = "Bewaldete Fläche in \n2020 (in 1000ha)",
    caption = "Quelle: Eurostat Datenbank (https://ec.europa.eu/eurostat/web/main/home)") +
  coord_map(projection = 'orthographic', orientation = c(55, 10,0),
    xlim = c(-10, 30), ylim = c(35,70)) +
  theme_minimal() +
  theme(panel.border = element_rect(color = "black", fill = NA, linewidth = .5))
wood_map

ggplot mit ggspatial

Lädt OpenStreetMap (OSM)-Karten als Hintergrund (ohne API-Key)

  • Funktion annotation_map_tile(type = "osm", zoom = 10) (zoom 1-19) lädt OSM-Kacheln.
  • Koordinatenreferenzsystem (CRS):
    • OSM-Kacheln sind in WGS84 (EPSG:4326) → in coord_sf(crs = 4326) setzen.
    • Ausschnitt: Per xlim/ylim in coord_sf
  • Attribution:
    • Pflicht! z. B. labs(caption = "© OpenStreetMap-Mitwirkende")

ggplot mit ggspatial | Beispiel

Code
library(ggspatial)

# Punkte an der Außenalster (long/lat, WGS84 = EPSG:4326)
df <- data.frame(
  long = c(10.001759, 10.001917, 10.002137, 10.001460, 10.000341),
  lat  = c(53.568823, 53.570160, 53.573229, 53.575446, 53.577307)
)
# Bounding Box in long/lat (EPSG:4326)
bb <- c(xmin = 9.95, ymin = 53.55, xmax = 10.05, ymax = 53.59)

# Karte erstellen
ggplot() +
  # Hintergrund-OSM-Kacheln hinzufügen
  annotation_map_tile(type = "osm", zoom = 13) +
  # Das Koordinatensystem spezifizieren
  coord_sf(crs = 4326,     # EPSG:4326 = WGS84 lon/lat
    xlim = bb[c("xmin", "xmax")],
    ylim = bb[c("ymin", "ymax")],
    expand = FALSE) +
  geom_point(data = df, aes(x = long, y = lat), color = "red", size = 3) +
  theme_void() +
  labs(caption = "© OpenStreetMap-Mitwirkende")

Interaktive Grafiken

HTML-Widgets | 1

Mithilfe des Softwareentwicklungs-Framework htmlwidgets gibt es nun R Schnittstellen für JavaScript (JS) Visualisierungsbibliotheken wie z.B

  • Plotly
    • mehr als 40 Diagrammtypen (statistische, 3D-Diagramme, SVG-Karten)
    • ➜ R Paket: plotly (https://plot.ly/r/)
    • neben der Bindung zur Plotly.js Biobliothek übersetzt das Paket auch ggplot2-Grafiken in eine interaktive, webbasierte Version
  • dygraphs - erstellt Diagramme für Zeitreihen ➜ R Paket: dygraphs (Link
  • Highcharts - beliebte JS Bibliothek für verschiedenste Diagrammtypen ➜ R Paket: highcharter (Link)

HTML-Widgets | 2

  • HTML-Widgets funktionieren genau wie R-Plots, nur dass sie interaktive Webvisualisierungen erzeugen.
  • Eine oder zwei Zeilen R-Code genügen, um eine D3-Grafik oder eine Leaflet-Karte zu erzeugen.
  • HTML-Widgets können sowohl in der R Konsole als auch eingebettet in R Markdown-Berichte und Shiny-Webanwendungen verwendet werden.
  • Alle Pakete arbeiten mit dem Pipe-Operator!

HTML-Widgets | Beispiele

plotly

leaflet

Von ggplot2 zu plotly

  • Mit ggplotply() können ggplot2 Grafiken ganz einfach in interaktive Diagramme umgewandeln werden!
gg_bill <- ggplot(data = palmerpenguins::penguins,  
  aes(x = bill_length_mm , y = body_mass_g, color = species)) + 
  geom_point()
ggplotly(gg_bill) # Umwandlung zu plotly Objekt

plotly | Menüleiste

Features

  • Download als PNG Datei
  • Zoomen
  • Legendenelemente auswählen
  • Hovering um Werte zu erhalten
  • ‘Home’ Schaltfläche
  • Schwenken
  • Automatische Skalierung
  • Reset
  • Vergleich von Datenpunkten beim Hovern


Anpassung

Mit der config() Funktion:

p_bill <- ggplotly(gg_bill)
# Menüleise komplett entfernen
config(p_bill, 
  displayModeBar = FALSE,
  displaylogo = FALSE,
  modeBarButtonsToRemove = c(
    'zoomIn2d', 'zoomOut2d'))

plotly Grafiken kombinieren | subplot()

p_bill <- ggplotly(gg_bill)
# Zweites Diagramm erstellen
gg_weight <- ggplot(penguins, aes(species, body_mass_g)) + geom_boxplot(aes(fill = sex))
p_weight <- ggplotly(gg_weight)
# In einer Zeile anordnen und relative Breite ändern, Legende ausblenden
subplot(p_bill, p_weight, nrows = 1, widths = c(0.7, 0.3)) |> hide_legend() 

Animationen mit plotly | Beispiel 1

  • Für Animationen muss das frame Aesthetic definiert werden!
anim_bill <- gg_bill + aes(frame = year)
ggplotly(anim_bill)

Animationen mit plotly | Beispiel 2

gg <- ggplot(gapminder::gapminder, aes(x = gdpPercap, y = lifeExp, 
      color = continent, size = pop, frame = year)) +
  geom_point() + scale_x_log10()
plotly::ggplotly(gg)

plotly | Mehr Möglichkeiten

  • Die Möglichkeiten mit ggplot2 und der Konvertierungsfunktion ggplotly() sind begrenzt.
  • Mehr Optionen gibt es bei der Verwendung von plotly’s eigener Syntax:
Code
library(reshape2)
library(tidyverse)
library(tidymodels)
library(plotly)
library(kernlab)
library(pracma) # Für meshgrid()

mesh_size <- .02
margin <- 0
X <- iris |> select(Sepal.Width, Sepal.Length)
y <- iris |> select(Petal.Width)

model <- svm_rbf(cost = 1.0) |> 
  set_engine("kernlab") |> 
  set_mode("regression") |> 
  fit(Petal.Width ~ Sepal.Width + Sepal.Length, data = iris)

x_min <- min(X$Sepal.Width) - margin
x_max <- max(X$Sepal.Width) - margin
y_min <- min(X$Sepal.Length) - margin
y_max <- max(X$Sepal.Length) - margin
xrange <- seq(x_min, x_max, mesh_size)
yrange <- seq(y_min, y_max, mesh_size)
xy <- meshgrid(x = xrange, y = yrange)
xx <- xy$X
yy <- xy$Y
dim_val <- dim(xx)
xx1 <- matrix(xx, length(xx), 1)
yy1 <- matrix(yy, length(yy), 1)
final <- cbind(xx1, yy1)
pred <- model |>
  predict(final)

pred <- pred$.pred
pred <- matrix(pred, dim_val[1], dim_val[2])

fig <- plot_ly(iris, x = ~Sepal.Width, y = ~Sepal.Length, z = ~Petal.Width, height = 700, width = 800) |> 
  add_markers(size = 5) |> 
  add_surface(x=xrange, y=yrange, z=pred, alpha = 0.65, type = 'mesh3d', name = 'pred_surface')
fig

plotly | Export als HTML- oder Bilddatei

Zum Speichern gibt es bei plotly 3 Möglichkeiten:

  1. Die GUI von RStudio/Posit nutzen.
  2. Die Download-Schaltfläche von Plotlys Menüleiste verwenden.

  1. Mit der saveWidget() Funktion im Paket htmlwidgets das Diagramm als HTML-Datei speichern und mit webshot() aus dem webshot2 Paket diese zu PNG umwandeln:
# Speichern im HTML-Format
htmlwidgets::saveWidget(widget = p_bill, file = "plotly-Diagramm.html")

# Umwandlung von HTML zu PNG, JPG,..
webshot2::webshot(url = "plotly-Diagramm.html", file = "plotly-Diagramm.png", 
  vwidth = 600, vheight = 480)

leaflet | Standardweltkarte

leaflet() und addTiles()

library(leaflet)
m <- leaflet() |>   # erstellt das Grundgerüst (ähnlich wie ggplot())
  addTiles()        # hinzufügen einer Karte -> Standard: OpenStreetMap
m

leaflet | Zoomen

setView()

Schwache Vergrößerung: zoom = 5
m |> setView(zoom = 5,
  lng = 9.97874, lat = 53.56745) 
Starke Vergrößerung: zoom = 20
m |> setView(zoom = 20,
  lng = 9.97874, lat = 53.56745) 

leaflet | Weitere Karten

addProviderTiles()

CartoDB.Positron
leaflet() |> setView(zoom = 12,
  lng = 9.97874, lat = 53.54545) |> 
  addProviderTiles(providers$CartoDB.Positron)
Esri.WorldPhysical
leaflet() |> 
  setView(lng = 10, lat = 53, zoom = 4) |> 
  addProviderTiles(providers$Esri.WorldPhysical)

leaflet | Karten kombinieren

Esri.WorldImagery mit OpenRailwayMap
leaflet() |> 
  setView(lng = 11, lat = 55, zoom = 8) |> 
  addProviderTiles(providers$Esri.WorldImagery) |> 
  addProviderTiles(providers$OpenRailwayMap)

Kartenübersicht

names(providers)
  [1] "OpenStreetMap"                         
  [2] "OpenStreetMap.Mapnik"                  
  [3] "OpenStreetMap.DE"                      
  [4] "OpenStreetMap.CH"                      
  [5] "OpenStreetMap.France"                  
  [6] "OpenStreetMap.HOT"                     
  [7] "OpenStreetMap.BZH"                     
  [8] "MapTilesAPI"                           
  [9] "MapTilesAPI.OSMEnglish"                
 [10] "MapTilesAPI.OSMFrancais"               
 [11] "MapTilesAPI.OSMEspagnol"               
 [12] "OpenSeaMap"                            
 [13] "OPNVKarte"                             
 [14] "OpenTopoMap"                           
 [15] "OpenRailwayMap"                        
 [16] "OpenFireMap"                           
 [17] "SafeCast"                              
 [18] "Stadia"                                
 [19] "Stadia.AlidadeSmooth"                  
 [20] "Stadia.AlidadeSmoothDark"              
 [21] "Stadia.OSMBright"                      
 [22] "Stadia.Outdoors"                       
 [23] "Stadia.StamenToner"                    
 [24] "Stadia.StamenTonerBackground"          
 [25] "Stadia.StamenTonerLines"               
 [26] "Stadia.StamenTonerLabels"              
 [27] "Stadia.StamenTonerLite"                
 [28] "Stadia.StamenWatercolor"               
 [29] "Stadia.StamenTerrain"                  
 [30] "Stadia.StamenTerrainBackground"        
 [31] "Stadia.StamenTerrainLabels"            
 [32] "Stadia.StamenTerrainLines"             
 [33] "Thunderforest"                         
 [34] "Thunderforest.OpenCycleMap"            
 [35] "Thunderforest.Transport"               
 [36] "Thunderforest.TransportDark"           
 [37] "Thunderforest.SpinalMap"               
 [38] "Thunderforest.Landscape"               
 [39] "Thunderforest.Outdoors"                
 [40] "Thunderforest.Pioneer"                 
 [41] "Thunderforest.MobileAtlas"             
 [42] "Thunderforest.Neighbourhood"           
 [43] "CyclOSM"                               
 [44] "Jawg"                                  
 [45] "Jawg.Streets"                          
 [46] "Jawg.Terrain"                          
 [47] "Jawg.Sunny"                            
 [48] "Jawg.Dark"                             
 [49] "Jawg.Light"                            
 [50] "Jawg.Matrix"                           
 [51] "MapBox"                                
 [52] "MapTiler"                              
 [53] "MapTiler.Streets"                      
 [54] "MapTiler.Basic"                        
 [55] "MapTiler.Bright"                       
 [56] "MapTiler.Pastel"                       
 [57] "MapTiler.Positron"                     
 [58] "MapTiler.Hybrid"                       
 [59] "MapTiler.Toner"                        
 [60] "MapTiler.Topo"                         
 [61] "MapTiler.Voyager"                      
 [62] "TomTom"                                
 [63] "TomTom.Basic"                          
 [64] "TomTom.Hybrid"                         
 [65] "TomTom.Labels"                         
 [66] "Esri"                                  
 [67] "Esri.WorldStreetMap"                   
 [68] "Esri.DeLorme"                          
 [69] "Esri.WorldTopoMap"                     
 [70] "Esri.WorldImagery"                     
 [71] "Esri.WorldTerrain"                     
 [72] "Esri.WorldShadedRelief"                
 [73] "Esri.WorldPhysical"                    
 [74] "Esri.OceanBasemap"                     
 [75] "Esri.NatGeoWorldMap"                   
 [76] "Esri.WorldGrayCanvas"                  
 [77] "OpenWeatherMap"                        
 [78] "OpenWeatherMap.Clouds"                 
 [79] "OpenWeatherMap.CloudsClassic"          
 [80] "OpenWeatherMap.Precipitation"          
 [81] "OpenWeatherMap.PrecipitationClassic"   
 [82] "OpenWeatherMap.Rain"                   
 [83] "OpenWeatherMap.RainClassic"            
 [84] "OpenWeatherMap.Pressure"               
 [85] "OpenWeatherMap.PressureContour"        
 [86] "OpenWeatherMap.Wind"                   
 [87] "OpenWeatherMap.Temperature"            
 [88] "OpenWeatherMap.Snow"                   
 [89] "HERE"                                  
 [90] "HERE.normalDay"                        
 [91] "HERE.normalDayCustom"                  
 [92] "HERE.normalDayGrey"                    
 [93] "HERE.normalDayMobile"                  
 [94] "HERE.normalDayGreyMobile"              
 [95] "HERE.normalDayTransit"                 
 [96] "HERE.normalDayTransitMobile"           
 [97] "HERE.normalDayTraffic"                 
 [98] "HERE.normalNight"                      
 [99] "HERE.normalNightMobile"                
[100] "HERE.normalNightGrey"                  
[101] "HERE.normalNightGreyMobile"            
[102] "HERE.normalNightTransit"               
[103] "HERE.normalNightTransitMobile"         
[104] "HERE.reducedDay"                       
[105] "HERE.reducedNight"                     
[106] "HERE.basicMap"                         
[107] "HERE.mapLabels"                        
[108] "HERE.trafficFlow"                      
[109] "HERE.carnavDayGrey"                    
[110] "HERE.hybridDay"                        
[111] "HERE.hybridDayMobile"                  
[112] "HERE.hybridDayTransit"                 
[113] "HERE.hybridDayGrey"                    
[114] "HERE.hybridDayTraffic"                 
[115] "HERE.pedestrianDay"                    
[116] "HERE.pedestrianNight"                  
[117] "HERE.satelliteDay"                     
[118] "HERE.terrainDay"                       
[119] "HERE.terrainDayMobile"                 
[120] "HEREv3"                                
[121] "HEREv3.normalDay"                      
[122] "HEREv3.normalDayCustom"                
[123] "HEREv3.normalDayGrey"                  
[124] "HEREv3.normalDayMobile"                
[125] "HEREv3.normalDayGreyMobile"            
[126] "HEREv3.normalDayTransit"               
[127] "HEREv3.normalDayTransitMobile"         
[128] "HEREv3.normalNight"                    
[129] "HEREv3.normalNightMobile"              
[130] "HEREv3.normalNightGrey"                
[131] "HEREv3.normalNightGreyMobile"          
[132] "HEREv3.normalNightTransit"             
[133] "HEREv3.normalNightTransitMobile"       
[134] "HEREv3.reducedDay"                     
[135] "HEREv3.reducedNight"                   
[136] "HEREv3.basicMap"                       
[137] "HEREv3.mapLabels"                      
[138] "HEREv3.trafficFlow"                    
[139] "HEREv3.carnavDayGrey"                  
[140] "HEREv3.hybridDay"                      
[141] "HEREv3.hybridDayMobile"                
[142] "HEREv3.hybridDayTransit"               
[143] "HEREv3.hybridDayGrey"                  
[144] "HEREv3.pedestrianDay"                  
[145] "HEREv3.pedestrianNight"                
[146] "HEREv3.satelliteDay"                   
[147] "HEREv3.terrainDay"                     
[148] "HEREv3.terrainDayMobile"               
[149] "FreeMapSK"                             
[150] "MtbMap"                                
[151] "CartoDB"                               
[152] "CartoDB.Positron"                      
[153] "CartoDB.PositronNoLabels"              
[154] "CartoDB.PositronOnlyLabels"            
[155] "CartoDB.DarkMatter"                    
[156] "CartoDB.DarkMatterNoLabels"            
[157] "CartoDB.DarkMatterOnlyLabels"          
[158] "CartoDB.Voyager"                       
[159] "CartoDB.VoyagerNoLabels"               
[160] "CartoDB.VoyagerOnlyLabels"             
[161] "CartoDB.VoyagerLabelsUnder"            
[162] "HikeBike"                              
[163] "HikeBike.HikeBike"                     
[164] "HikeBike.HillShading"                  
[165] "BasemapAT"                             
[166] "BasemapAT.basemap"                     
[167] "BasemapAT.grau"                        
[168] "BasemapAT.overlay"                     
[169] "BasemapAT.terrain"                     
[170] "BasemapAT.surface"                     
[171] "BasemapAT.highdpi"                     
[172] "BasemapAT.orthofoto"                   
[173] "nlmaps"                                
[174] "nlmaps.standaard"                      
[175] "nlmaps.pastel"                         
[176] "nlmaps.grijs"                          
[177] "nlmaps.water"                          
[178] "nlmaps.luchtfoto"                      
[179] "NASAGIBS"                              
[180] "NASAGIBS.ModisTerraTrueColorCR"        
[181] "NASAGIBS.ModisTerraBands367CR"         
[182] "NASAGIBS.ViirsEarthAtNight2012"        
[183] "NASAGIBS.ModisTerraLSTDay"             
[184] "NASAGIBS.ModisTerraSnowCover"          
[185] "NASAGIBS.ModisTerraAOD"                
[186] "NASAGIBS.ModisTerraChlorophyll"        
[187] "NLS"                                   
[188] "JusticeMap"                            
[189] "JusticeMap.income"                     
[190] "JusticeMap.americanIndian"             
[191] "JusticeMap.asian"                      
[192] "JusticeMap.black"                      
[193] "JusticeMap.hispanic"                   
[194] "JusticeMap.multi"                      
[195] "JusticeMap.nonWhite"                   
[196] "JusticeMap.white"                      
[197] "JusticeMap.plurality"                  
[198] "GeoportailFrance"                      
[199] "GeoportailFrance.plan"                 
[200] "GeoportailFrance.parcels"              
[201] "GeoportailFrance.orthos"               
[202] "OneMapSG"                              
[203] "OneMapSG.Default"                      
[204] "OneMapSG.Night"                        
[205] "OneMapSG.Original"                     
[206] "OneMapSG.Grey"                         
[207] "OneMapSG.LandLot"                      
[208] "USGS"                                  
[209] "USGS.USTopo"                           
[210] "USGS.USImagery"                        
[211] "USGS.USImageryTopo"                    
[212] "WaymarkedTrails"                       
[213] "WaymarkedTrails.hiking"                
[214] "WaymarkedTrails.cycling"               
[215] "WaymarkedTrails.mtb"                   
[216] "WaymarkedTrails.slopes"                
[217] "WaymarkedTrails.riding"                
[218] "WaymarkedTrails.skating"               
[219] "OpenAIP"                               
[220] "OpenSnowMap"                           
[221] "OpenSnowMap.pistes"                    
[222] "AzureMaps"                             
[223] "AzureMaps.MicrosoftImagery"            
[224] "AzureMaps.MicrosoftBaseDarkGrey"       
[225] "AzureMaps.MicrosoftBaseRoad"           
[226] "AzureMaps.MicrosoftBaseHybridRoad"     
[227] "AzureMaps.MicrosoftTerraMain"          
[228] "AzureMaps.MicrosoftWeatherInfraredMain"
[229] "AzureMaps.MicrosoftWeatherRadarMain"   
[230] "SwissFederalGeoportal"                 
[231] "SwissFederalGeoportal.NationalMapColor"
[232] "SwissFederalGeoportal.NationalMapGrey" 
[233] "SwissFederalGeoportal.SWISSIMAGE"      

leaflet | Hinzufügen von Elementen 1

Rechtecke und Markierungspunkte

addMarkers(), addCircleMarkers() und addRectangles()

Code
long <- 9.9789
lat <- 53.5675
m <- leaflet() |>
  addTiles() |>
  setView(lng = long, lat = lat, zoom = 20) |>
  # Rechteck:
  addRectangles(
    lng1 = 9.978, lat1 = 53.5671,
    lng2 = 9.9795, lat2 = 53.5679,
    fillColor = "transparent") |> 
  # sog. Icon Markers:
  addMarkers(lng = long, lat = lat,
    popup = "Eingang des Instituts für Zell- und Systembiologie der Tiere (IZS)", 
    label = "IZS") |>
  # Kreismarkierung:
  addCircleMarkers(lng = 9.97925, lat = 53.56735,
    popup = "Gr. Hörsaal der Zoologie", label = "Unser Standort",
    color = "red", radius = 35, stroke = TRUE, opacity = 0.5,
    weight = 3, fill = TRUE, fillColor = "red", fillOpacity = 0.2)
m

leaflet | Hinzufügen von Elementen 2

Gruppierte Markierungspunkte

addMarkers()

Code
df <- data.frame(
  station = paste("S", 1:5),
  long = c(10.001759, 10.001917, 10.002137, 10.001460, 10.000341),
  lat  = c(53.568823, 53.570160, 53.573229, 53.575446, 53.577307)
)

m <- leaflet() |>
  addTiles() |>
  setView(lng = 10.005, lat = 53.572, zoom = 13) |>
  addProviderTiles("Esri.WorldTopoMap")

# sog. Icon Markers:
m <- m |> 
  addMarkers(
    lng = df$long, 
    lat = df$lat,
    label = df$station,
    popup = paste("Station:", df$station),
    clusterOptions = markerClusterOptions()
  ) 
m

leaflet | Export als HTML- oder Bilddatei

Zum Speichern gibt es 2 Möglichkeiten:

  1. Die GUI von RStudio/Posit nutzen.

  1. Mit der saveWidget() und webshot() Funktion wie bei plotply:
# Speichern im HTML-Format
htmlwidgets::saveWidget(widget = m, file = "leaflet-Karte.html")
# Umwandlung von HTML zu PNG, JPG,..
webshot2::webshot(url = "leaflet-Karte.html", file = "leaflet-Karte.png", 
  vwidth = 805, vheight = 480)

Übungsaufgabe

Optionale swirl-Lektionen zur Vertiefung

Kurs DSB-04-Datenvisualisierung mit ggplot2

  • L13-Plots kombinieren
  • L14-Karten erstellen mit ggplot2
  • L15-Umwandlung zur interaktiven plotly_Grafik
  • L16-plotly Objekte besser verstehen

Übungsskripte


  • Schauen Sie sich das VL-begleitende R Skript an und experimentieren Sie mit den Einstellungen: DS1_W12_Vorlesungsskript_ggplot2_Erweiterungen_Karten.R

Fallstudie

Sie sind jetzt so weit, …

..dass Sie versuchen können, mindestens eine statische und eine dynamische Karte zu Ihrer Fallstudie zu erstellen (letzteres z.B. über die Umwandlung der ggplot2 Karte zu einem plotly Objekt oder über die Erstellung einer leaflet Karte).

Wie fühlen Sie sich jetzt…?

Total konfus?


Bei weiteren Fragen: saskia.otto(at)uni-hamburg.de

Creative Commons License
Diese Arbeit is lizenziert unter einer Creative Commons Attribution-ShareAlike 4.0 International License mit Ausnahme der entliehenen und mit Quellenangabe versehenen Abbildungen.