Kartenbasierte Streudiagramme mit deckgl in R

Ich zeige in diesem Beitrag wie man mit deckgl in R kartenbasierte Streudiagramme erzeugen kann.

Eine Voraussetzung für die Verwendung von deckgl zur Visualisierung von räumlichen bzw. ortsbezogenen Daten ist, dass jeder Observation Koordinaten in Form von Longitude und Latitude zugeordnet werden. Sollten diese Koordinaten noch nicht vorliegen so kann hierfür die Open Street Map API verwendet werden.

Die Open Street Map API empfängt bspw. Ortsnamen als Strings und retourniert Koordinaten in JSON-Format. Zur Auswertung der Rückmeldungen empfiehlt sich also die Anwendung des jsonlite-Pakets.

Nachstehend habe ich eine Funktion implementiert, welche ich von datascienceplus.com übernommen habe. Die Funktion übergibt Adressen an die OSM API und empfängt die Rückmeldungen der OSM API. Diesen Prozess bezeichne ich als „Geocoding“

# osm geocoding
# quelle: https://datascienceplus.com/osm-nominatim-with-r-getting-locations-geo-coordinates-by-its-address/
osm_geocoder <- function(address = NULL)
{
  if(suppressWarnings(is.null(address)))
    return(data.frame())
  
  tryCatch(
    d <- jsonlite::fromJSON( 
      gsub('\\@addr\\@', gsub('\\s+', '\\%20', address), 
           'http://nominatim.openstreetmap.org/search/@addr@?format=json&addressdetails=0&limit=1')
    ), error = function(c) return(data.frame())
  )
  
  if(length(d) == 0) 
    return(data.frame())
  
  return(data.frame(lon = as.numeric(d$lon), lat = as.numeric(d$lat)))
}

In einer csv-Datei habe ich eine Liste von Ortsnamen hinterlegt. Ich lese diese Liste ein, führe den „Geocoding“-Prozess für jeden Ortsnamen durch und speichere Ortsnamen mit dazugehörigen Koordinaten in einer DataFrame-Tabelle ab. Daraufhin ordne ich jedem Ortsnamen einen Zufallsverteilten Observationswert zu. Dieser wird den Durchmesser der Kreise im späteren Streudiagramm bestimmen:

# relevante Pakete einlesen
library(deckgl)
library(magrittr)
library(jsonlite)
library(dplyr)
# dataframe erzeugen
scatter_data_df_1 <- data.frame(matrix(nrow=30,ncol=6))

column_names <- c("name","code","address","entries","exits","coordinates")
colnames(scatter_data_df_1) <- column_names

city_list_1_df <- read.csv("city list 1.csv",header = FALSE, stringsAsFactors = FALSE)

# geocoding für jeden ortsnamen in der liste durchführen
for(i in 1:nrow(city_list_1_df)){
  dum_coord <- osm_geocoder(toString(city_list_1_df$V1[i]))
  scatter_data_df_1$name[i] <- paste0("city liste 1 : ",i)
  scatter_data_df_1$code[i] <- c("CL1")
  scatter_data_df_1$address[i] <- toString(city_list_1_df$V1[i])
  scatter_data_df_1$entries[i] <- as.integer(rnorm(1,mean=3000,sd=1000))
  scatter_data_df_1$exits[i] <- as.integer(rnorm(1,mean=3000,1000))
  scatter_data_df_1$coordinates[i] <- list(c(as.numeric(dum_coord[1]),as.numeric(dum_coord[2])))
}

# kopf der dataframe-tabelle ausgeben
head(scatter_data_df_1)
##               name code            address entries exits
## 1 city liste 1 : 1  CL1     Berlin Germany    5008  3112
## 2 city liste 1 : 2  CL1  Karlsruhe Germany    2002  2223
## 3 city liste 1 : 3  CL1  Stuttgart Germany    3453  3498
## 4 city liste 1 : 4  CL1   Mannheim Germany    2478  3041
## 5 city liste 1 : 5  CL1 Heidelberg Germany    3811  1003
## 6 city liste 1 : 6  CL1  Frankfurt Germany    1875  3135
##           coordinates
## 1  13.38886, 52.51704
## 2   8.40342, 49.00687
## 3 9.180013, 48.778449
## 4 8.467236, 49.489591
## 5 8.694724, 49.409358
## 6 8.682092, 50.110644

Ich kann nun ein Streudiagramm mit deckgl in R erzeugen:

# eigenschaften des streudiagramms festlegen
properties_1 <- list(
  getPosition = get_property("coordinates"),
  getRadius = JS("data => Math.sqrt(data.exits)"),
  radiusScale = 1000,
  getColor = c(255, 153, 77)
)

# streudiagramm erzeugen bzw. darstellen
deckgl(zoom = 10.5, pitch = 35, longitude = 8.40342, latitude = 40.00687) %>%
  add_scatterplot_layer(data = scatter_data_df_1, properties = properties_1) %>%
  add_mapbox_basemap(style = "mapbox://styles/linnartsf/cjq6p9q8f8zwf2rp74qf2o3d5")

Es entsteht so nachstehendes Streudiagramm:

Einfaches Streudiagramm mit deckgl in R

You May Also Like

Leave a Reply

Leave a Reply

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

Diese Seite verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden..