ggplot2 Erweiterungen: Diagramme kombinieren, Kartenerstellung und interaktive Grafikeny

Data Science 1 - Programmieren & Visualisieren

Saskia Otto

Universität Hamburg, IMF

Wintersemester 2022/2023

Lernziele

Am Ende dieser Übungseinheit sollten Sie …

  • …ggplot2 Diagramme mit dem Paket gridExtra oder grid bzw. cowplot kombinieren können.
  • einfache Karten mit dem ggplot2 Paket erstellen können.
  • zusätzliche Karten (z.B. Stamen-Karten) mit dem Paket ggmap abgreifen können.
  • …einen Überblick weiterer, aktuell beliebter R Paket zu statischen Karten haben.
  • interaktive Karten mit dem Paket leaflet erstellen können.
  • statische Diagramme und Karten von ggplot2 zu interaktiven plotly Grafiken umkonvertieren können.

Diagramme kombinieren

Übersicht an R Paketen und Funktionen

  • Für ‘ggplot’ Objekte funktionieren die Standard R Funktionen par() und layout() nicht
  • Alternative Funktionen:
  • 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)

Verschachtelte Diagramme

→ mit viewport()

Um ein kleines Diagramm in ein Hauptdiagramm einzubetten…

  1. erstellen Sie zuerst das Hauptdiagramm,
  2. dann spezifizieren Sie in der viewport() Funktion, wo im Koordinatensystem des Hauptdiagramms das kleinere Diagramm abgebildet werden soll, und speichern es als Objekt ab.
  3. Zeichnen Sie abschließend das kleinere Diagramm mit der print() Funktion, wobei das viewport Objekt dem vp Argument zugewiesen wird:
b # Hauptdiagramm
subvp <- grid::viewport(x = 0.6, y = 0.7,
  width = 0.4, height = 0.4)
print(a, vp = subvp)

Kombinieren mehrerer Diagramme | 1

→ mit grid.arrange()

Die Funktion

  • erstellt ein sogenanntes ‘gtable’ Layout um mehrere grafische Objekte (=‘grobs’) auf einer Seite zu platzieren.
  • nimmt für das Gitter-Layout Anzahl der Zeilen und Spalten als Argumente:
library(gridExtra)
grid.arrange(a, b, c, nrow = 2, ncol = 2)

Kombinieren mehrerer Diagramme | 2

→ eigene Aufteilung mit arrangeGrob() zusätzlich

grid.arrange(
  arrangeGrob(a, b, ncol = 2), 
  c, nrow = 2)

  • Um einzelne Zeilen oder Spalten noch weiter aufzuteilen, verwende die Helferfunktion arrangeGrob() beim Auflisten der Plotobjekte.
  • Diese Funktion nimmt auch die Anzahl der Zeilen oder Spalten als Input.
  • Im Beispiel rechts werden a und b als ein grafisches Objekt gehandelt und bekommen den gleichen Platz zugesprochen wie c alleine (jeweils eine Zeile).

Kombinieren mehrerer Diagramme | 3

→ noch flexibler als die Funktion arrangeGrob() ist das Argument layout_matrix:

Erstellung der Layout-Matrix
my_mat <- matrix(c(1,2,2,3,3,3), 
  nrow = 2, byrow = TRUE)
my_mat
     [,1] [,2] [,3]
[1,]    1    2    2
[2,]    3    3    3

6 Rasterzellen sind in der Matrix spezifiziert:

  • Plot a bekommt 1 Zelle (Zeile 1, Spalte 1)
  • Plot b bekommt 2 Zellen (Zeile 1, Spalte 2-3)
  • Plot c bekommt 3 Zellen (Zeile 2, Spalte 1-3)
Übergabe der Layout-Matrix
grid.arrange(a, b, c, layout_matrix = my_mat)

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 eine einzelnen Plot auf die Leinwand
  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) )

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

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

+ borders()

# Grundplot (Streudiagramm mit Hauptstädten)
ggplot(capitals, aes(x = long, y = lat)) +
  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
# Einfügen neuer 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

Karten mit ‘ggmap’ erstellen

ggmap() im ggmap Paket

library(ggmap)
# Europa-Ausschnitt wählen
euro_bbox <- c(left = -10, bottom = 35, 
  right = 30, top = 65)

# Stamen Karte abgreifen mit 
# get_stamenmap()
stm <- get_stamenmap(
  bbox = euro_bbox, 
  zoom = 5, 
  maptype = 'terrain'
) # alternativ: 'watercolor', 'toner'

# Karte plotten mit ggmap()
ggmap(stm) +
  geom_point(
    data = european_capitals, 
    mapping = aes(x = long, y = lat), 
    colour = 'red', size = 2
  )

Weitere Pakete zur Kartenerstellung

ggplot mit ggspatial

  • ggspatial bietet Funktionen zur Visualisierung von räumlichen Daten unter Verwendung von ggplot2 als Plotting-Backend.
  • Das Paket unterstützt sf-, sp- und raster-Objekte und benutzt intern geom_sf() und coord_sf() für die Koordinatentransformation.
  • Vignette für den Einstieg:

ggplot mit ggspatial | Beispiel

Code
library(ggplot2)
library(ggspatial)
load_longlake_data()

ggplot() +
  # lädt Hintergrundkartenkacheln aus einer Kachelquelle
  annotation_map_tile(zoomin = -1) +
  
  # annotation_spatial()-Schichten trainieren die Skalen nicht, 
  # so dass die Daten zentral bleiben
  annotation_spatial(longlake_roadsdf, size = 2, col = "black") +
  annotation_spatial(longlake_roadsdf, size = 1.6, col = "white") +

  # Rasterebenen trainieren Skalen und werden automatisch projiziert
  layer_spatial(longlake_depth_raster, aes(colour = after_stat(band1))) +
  # fehlende Werte nicht anzeigen
  scale_fill_viridis_c(na.value = NA) +
  
  # layer_spatial bildet die Skalen aus
  layer_spatial(longlake_depthdf, aes(fill = DEPTH_M)) +
  
  # hinzufügen eines Maßstabsbalken
  annotation_scale(location = "tl") +

  # hinzufügen eines Nordpfeils
  annotation_north_arrow(location = "br", which_north = "true")

Das tmap Paket

tmaps ‘Grammar of graphics’

  • Grammar of Graphics angewandt auf die Visualisierung räumlicher Daten
  • Alternative zu ggplot2:
    • pro: Räumliche Objekte (aus den Paketen sp, raster und sf) können direkt verwendet werden
    • pro: Für Karten optimiertes Layout (z. B. Legende, Kartenattribute)
    • con: Ein weiteres Paket zum Lernen …

tmap | Beispiel - Punktkartogramm

Code
library(tmap)
# Beispieldaten laden 
data(World, metro, rivers, land)

tmap_mode("plot")
## tmap-Modus auf Plotten eingestellt
tm_shape(land) +
    tm_raster("elevation", palette = terrain.colors(10)) +
tm_shape(World) +
    tm_borders("white", lwd = .5) +
    tm_text("iso_a3", size = "AREA") +
tm_shape(metro) +
    tm_symbols(col = "red", size = "pop2020", scale = 1.5) +
tm_legend(show = FALSE)

Das mapsf Paket

mapsf | Beispiel - Punktkartogramm

Code
library(mapsf)
# Beispieldaten laden
mtq <- mf_get_mtq()
# Theme festlegen
mf_init(x = mtq, theme = "candy", expandBB = c(0, 0, 0, .15))
# Schatten erzeugen
mf_shadow(mtq, add = TRUE)
# Gemeinden plotten
mf_map(mtq, add = TRUE)
# Punktsymbole mit Choroplethenfärbung 
mf_map(
  x = mtq,
  var = c("POP", "MED"),
  type = "prop_choro",
  border = "grey50",
  lwd = 1,
  leg_pos = c("topright", "right"),
  leg_title = c("Population", "Median\nIncome\n(in euros)"),
  breaks = "equal",
  nbreaks = 4,
  pal = "Greens",
  leg_val_rnd = c(0, -2),
  leg_frame = c(TRUE, TRUE)
)
# Layout
mf_layout(
  title = "Population & Wealth in Martinique, 2015",
  credits = paste0(
    "Sources: Insee and IGN, 2018\n",
    "mapsf ",
    packageVersion("mapsf")
  ),
  frame = TRUE
)

Interaktive Grafiken

HTML-Widgets | 1

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

Alle Pakete arbeiten mit dem Pipe-Operator!

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 1

leaflet

plotly

HTML-Widgets | Beispiele 2

dygraphs

highcharter

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 - Stamen

addProviderTiles()

Stamen.Toner
m <- leaflet() |> 
  setView(lng = 7.5, lat = 45, zoom = 5)
m |> addProviderTiles(providers$Stamen.Toner)
Stamen.Terrain
m <- leaflet() |> 
  setView(lng = 7.5, lat = 45, zoom = 7)
m |> addProviderTiles(providers$Stamen.Terrain)

Infos zu Stamen-Karten: http://maps.stamen.com/

leaflet | Weitere Karten - Esri

addProviderTiles()

Esri.WorldPhysical
m <- leaflet() |> 
  setView(lng = 10, lat = 53, zoom = 4)
m |> addProviderTiles(providers$Esri.WorldPhysical)
Esri.OceanBasemap
m <- leaflet() |> 
  setView(lng = -43.8, lat = 26.6, zoom = 3)
m |> addProviderTiles(providers$Esri.OceanBasemap)

leaflet | Karten kombinieren

Esri.WorldImagery mit Stamen.TonerLabels
m <- leaflet() |> 
  setView(lng = 10, lat = 53, zoom = 3)
m |> addProviderTiles(providers$Esri.WorldImagery) |> 
  addProviderTiles(providers$Stamen.TonerLabels)

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] "OpenSeaMap"                         
  [9] "OpenPtMap"                          
 [10] "OpenTopoMap"                        
 [11] "OpenRailwayMap"                     
 [12] "OpenFireMap"                        
 [13] "SafeCast"                           
 [14] "Thunderforest"                      
 [15] "Thunderforest.OpenCycleMap"         
 [16] "Thunderforest.Transport"            
 [17] "Thunderforest.TransportDark"        
 [18] "Thunderforest.SpinalMap"            
 [19] "Thunderforest.Landscape"            
 [20] "Thunderforest.Outdoors"             
 [21] "Thunderforest.Pioneer"              
 [22] "Thunderforest.MobileAtlas"          
 [23] "Thunderforest.Neighbourhood"        
 [24] "OpenMapSurfer"                      
 [25] "OpenMapSurfer.Roads"                
 [26] "OpenMapSurfer.Hybrid"               
 [27] "OpenMapSurfer.AdminBounds"          
 [28] "OpenMapSurfer.ContourLines"         
 [29] "OpenMapSurfer.Hillshade"            
 [30] "OpenMapSurfer.ElementsAtRisk"       
 [31] "Hydda"                              
 [32] "Hydda.Full"                         
 [33] "Hydda.Base"                         
 [34] "Hydda.RoadsAndLabels"               
 [35] "MapBox"                             
 [36] "Stamen"                             
 [37] "Stamen.Toner"                       
 [38] "Stamen.TonerBackground"             
 [39] "Stamen.TonerHybrid"                 
 [40] "Stamen.TonerLines"                  
 [41] "Stamen.TonerLabels"                 
 [42] "Stamen.TonerLite"                   
 [43] "Stamen.Watercolor"                  
 [44] "Stamen.Terrain"                     
 [45] "Stamen.TerrainBackground"           
 [46] "Stamen.TerrainLabels"               
 [47] "Stamen.TopOSMRelief"                
 [48] "Stamen.TopOSMFeatures"              
 [49] "TomTom"                             
 [50] "TomTom.Basic"                       
 [51] "TomTom.Hybrid"                      
 [52] "TomTom.Labels"                      
 [53] "Esri"                               
 [54] "Esri.WorldStreetMap"                
 [55] "Esri.DeLorme"                       
 [56] "Esri.WorldTopoMap"                  
 [57] "Esri.WorldImagery"                  
 [58] "Esri.WorldTerrain"                  
 [59] "Esri.WorldShadedRelief"             
 [60] "Esri.WorldPhysical"                 
 [61] "Esri.OceanBasemap"                  
 [62] "Esri.NatGeoWorldMap"                
 [63] "Esri.WorldGrayCanvas"               
 [64] "OpenWeatherMap"                     
 [65] "OpenWeatherMap.Clouds"              
 [66] "OpenWeatherMap.CloudsClassic"       
 [67] "OpenWeatherMap.Precipitation"       
 [68] "OpenWeatherMap.PrecipitationClassic"
 [69] "OpenWeatherMap.Rain"                
 [70] "OpenWeatherMap.RainClassic"         
 [71] "OpenWeatherMap.Pressure"            
 [72] "OpenWeatherMap.PressureContour"     
 [73] "OpenWeatherMap.Wind"                
 [74] "OpenWeatherMap.Temperature"         
 [75] "OpenWeatherMap.Snow"                
 [76] "HERE"                               
 [77] "HERE.normalDay"                     
 [78] "HERE.normalDayCustom"               
 [79] "HERE.normalDayGrey"                 
 [80] "HERE.normalDayMobile"               
 [81] "HERE.normalDayGreyMobile"           
 [82] "HERE.normalDayTransit"              
 [83] "HERE.normalDayTransitMobile"        
 [84] "HERE.normalDayTraffic"              
 [85] "HERE.normalNight"                   
 [86] "HERE.normalNightMobile"             
 [87] "HERE.normalNightGrey"               
 [88] "HERE.normalNightGreyMobile"         
 [89] "HERE.normalNightTransit"            
 [90] "HERE.normalNightTransitMobile"      
 [91] "HERE.reducedDay"                    
 [92] "HERE.reducedNight"                  
 [93] "HERE.basicMap"                      
 [94] "HERE.mapLabels"                     
 [95] "HERE.trafficFlow"                   
 [96] "HERE.carnavDayGrey"                 
 [97] "HERE.hybridDay"                     
 [98] "HERE.hybridDayMobile"               
 [99] "HERE.hybridDayTransit"              
[100] "HERE.hybridDayGrey"                 
[101] "HERE.hybridDayTraffic"              
[102] "HERE.pedestrianDay"                 
[103] "HERE.pedestrianNight"               
[104] "HERE.satelliteDay"                  
[105] "HERE.terrainDay"                    
[106] "HERE.terrainDayMobile"              
[107] "FreeMapSK"                          
[108] "MtbMap"                             
[109] "CartoDB"                            
[110] "CartoDB.Positron"                   
[111] "CartoDB.PositronNoLabels"           
[112] "CartoDB.PositronOnlyLabels"         
[113] "CartoDB.DarkMatter"                 
[114] "CartoDB.DarkMatterNoLabels"         
[115] "CartoDB.DarkMatterOnlyLabels"       
[116] "CartoDB.Voyager"                    
[117] "CartoDB.VoyagerNoLabels"            
[118] "CartoDB.VoyagerOnlyLabels"          
[119] "CartoDB.VoyagerLabelsUnder"         
[120] "HikeBike"                           
[121] "HikeBike.HikeBike"                  
[122] "HikeBike.HillShading"               
[123] "BasemapAT"                          
[124] "BasemapAT.basemap"                  
[125] "BasemapAT.grau"                     
[126] "BasemapAT.overlay"                  
[127] "BasemapAT.highdpi"                  
[128] "BasemapAT.orthofoto"                
[129] "nlmaps"                             
[130] "nlmaps.standaard"                   
[131] "nlmaps.pastel"                      
[132] "nlmaps.grijs"                       
[133] "nlmaps.luchtfoto"                   
[134] "NASAGIBS"                           
[135] "NASAGIBS.ModisTerraTrueColorCR"     
[136] "NASAGIBS.ModisTerraBands367CR"      
[137] "NASAGIBS.ViirsEarthAtNight2012"     
[138] "NASAGIBS.ModisTerraLSTDay"          
[139] "NASAGIBS.ModisTerraSnowCover"       
[140] "NASAGIBS.ModisTerraAOD"             
[141] "NASAGIBS.ModisTerraChlorophyll"     
[142] "NLS"                                
[143] "JusticeMap"                         
[144] "JusticeMap.income"                  
[145] "JusticeMap.americanIndian"          
[146] "JusticeMap.asian"                   
[147] "JusticeMap.black"                   
[148] "JusticeMap.hispanic"                
[149] "JusticeMap.multi"                   
[150] "JusticeMap.nonWhite"                
[151] "JusticeMap.white"                   
[152] "JusticeMap.plurality"               
[153] "Wikimedia"                          
[154] "GeoportailFrance"                   
[155] "GeoportailFrance.parcels"           
[156] "GeoportailFrance.ignMaps"           
[157] "GeoportailFrance.maps"              
[158] "GeoportailFrance.orthos"            
[159] "OneMapSG"                           
[160] "OneMapSG.Default"                   
[161] "OneMapSG.Night"                     
[162] "OneMapSG.Original"                  
[163] "OneMapSG.Grey"                      
[164] "OneMapSG.LandLot"                   

leaflet | Hinzufügen von Elementen 1

Rechtecke und Markierungspunkte

addMarkers(), addCircleMarkers() und addRectangles()

Code
lng <- 9.9789
lat <- 53.5675
m <- leaflet() |>
  addTiles() |>
  setView(lng = lng, 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 = lng, 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 | Export als HTML- oder Bilddatei

Zum Speichern gibt es 2 Möglichkeiten:

  1. Die GUI von RStudio/Posit nutzen.

  1. Mit der saveWidget() Funktion im Paket htmlwidgets die Karte als HTML-Datei speichern und mit webshot() aus dem webshot2 Paket diese zu PNG umwandeln:
htmlwidgets::saveWidget(widget = m, file = "leaflet-Karte.html")
webshot2::webshot(url = "leaflet-Karte.html", file = "leaflet-Karte.png", 
  vwidth = 805, vheight = 480)

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 | Anzeige beim ‘Mouseover’ 1

  • Standardmäßig werden alle Infos von Variablen im ‘Tooltip’ angezeigt, die den definierten Aesthetics zugewiesen wurden.
Anpassungen über das 'tooltip' Argument
ggplotly(gg_bill, tooltip = 'all') # Standardeinstellung
ggplotly(gg_bill, tooltip = 'species') # zeigt nur Infos der species Variable
ggplotly(gg_bill, tooltip = 'colour') # Alternativ: Aestheticnamen verwenden
ggplotly(gg_bill, tooltip = c('bill_length_mm', 'species')) # zeigt Infos von 2 Var.

plotly | Anzeige beim ‘Mouseover’ 2

  • Nicht definierte (sichtbare) Variablen, die im Tooltip aber erscheinen sollen, müssen den Aesthetics label, text oder group zugewiesen werden:
Anzeige nicht sichtbarer Variablen
gg_bill2 <- gg_bill +
  aes(group = island, label = body_mass_g , text = sex)     # text zeigt nicht den
ggplotly(gg_bill2, tooltip = c('group', 'label', 'text'))    # Variablennamen an!

plotly | Anzeige beim ‘Mouseover’ 3

  • Hilfreich beim Identifizieren von Datenpunkten ist die Vergabe einer Zeilen-ID, die dann dem Aesthetic ids übergeben wird:
Anzeige der ID im Tooltip
p <- penguins |> 
  mutate(id = 1:nrow(penguins)) |>  # falls es nicht schon eine ID gibt
  ggplot(aes(x = bill_length_mm , y = body_mass_g, color = species, ids = id)) +
  geom_point()
plotly::ggplotly(p)

plotly Grafiken kombinieren

  • Die Funktion subplot() im plotly Paket ist ähnlich wie die Funktion grid.arrange() Funktion aus dem gridExtra Paket
p_bill <- ggplotly(gg_bill)
# Erstelle zweites Diagramm
gg_weight <- drop_na(penguins, sex) |> 
  ggplot(aes(x = species, y = 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, gg_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 | Export als HTML- oder Bilddatei

Zum Speichern gibt es bei plotly 3 Möglichkeiten:

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

  1. Mit den saveWidget() und webshot() Funktionen wie bei leaflet:
# 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)

plotly | Mehr Möglichkeiten

  • Die Möglichkeiten mit ggplot2 und der Konvertierungsfunktion ggplotly() sind begrenzt.
  • Mehr Optionen gibt es bei der Verwendung von plotlys 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 ) |> 
  add_markers(size = 5) |> 
  add_surface(x=xrange, y=yrange, z=pred, alpha = 0.65, type = 'mesh3d', name = 'pred_surface')
fig

Übungsaufgabe

Begleitende Swirl-Lektionen

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

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.