Spatial Data Visualization with R

Mahdi Salehi

Associate professor at University of Neyshabur

Last update: 2025

Contents




- Part I: Various spatial data classes in R


- Part II: Creating maps and visualization of spatial data using tmap package


- Part III: Creating maps and visualization of spatial data using ggplot2 package

Part I:



Various spatial data classes in R



Spatial class

Spatial class is the base spatial data class in R provided by sp package. It has only two slots. The first is a bounding box, a matrix of numerical coordinates with column names c(‘min’, ‘max’), and at least two rows, with the first row eastings (x-axis) and the second northings (y-axis). Most often the bounding box is generated automatically from the data in subclasses of Spatial. The second is a CRS class object defining the coordinate reference system [Roger et al., 2008].

library(sp)
getClass("Spatial")
## Class "Spatial" [package "sp"]
## 
## Slots:
##                               
## Name:         bbox proj4string
## Class:      matrix         CRS
## 
## Known Subclasses: 
## Class "SpatialPoints", directly
## Class "SpatialMultiPoints", directly
## Class "SpatialGrid", directly
## Class "SpatialLines", directly
## Class "SpatialPolygons", directly
## Class "SpatialPointsDataFrame", by class "SpatialPoints", distance 2
## Class "SpatialPixels", by class "SpatialPoints", distance 2
## Class "SpatialMultiPointsDataFrame", by class "SpatialMultiPoints", distance 2
## Class "SpatialGridDataFrame", by class "SpatialGrid", distance 2
## Class "SpatialLinesDataFrame", by class "SpatialLines", distance 2
## Class "SpatialPixelsDataFrame", by class "SpatialPoints", distance 3
## Class "SpatialPolygonsDataFrame", by class "SpatialPolygons", distance 2

CRS: Coordinate reference system

This class has a character string as its only slot value, which may be a missing value. If it is not missing, it should be a PROJ.4-format string describing the projection [see Roger et al., Section, 2008]

getClass("CRS")
## Class "CRS" [package "sp"]
## 
## Slots:
##                 
## Name:   projargs
## Class: character

For geographical coordinates, the simplest such string is “+proj=longlat”, using “longlat”, which also shows that eastings always go before northings in sp classes.

For more details on crs, see https://www.earthdatascience.org/courses/earth-analytics/spatial-data-r/intro-to-coordinate-reference-systems/

A simple example

m <- matrix(c(0, 0, 1, 1), ncol = 2, dimnames = list(NULL, c("min", "max")))
crs <- CRS(projargs = as.character(NA))
crs
## Coordinate Reference System:
## Deprecated Proj.4 representation: NA
s <- Spatial(bbox = m, proj4string = crs)
s
## An object of class "Spatial"
## Slot "bbox":
##      min max
## [1,]   0   1
## [2,]   0   1
## 
## Slot "proj4string":
## Coordinate Reference System:
## Deprecated Proj.4 representation: NA

SpatialPoints class

It is the first subclass of Spatial and is very important. A two-dimensional point can be described by a pair of numbers (x, y), defined over a known region. To represent geographical phenomena, the maximum known region is the earth, and the pair of numbers measured in degrees are a geographical coordinate, showing where our point is on the globe. The pair of numbers define the location on the sphere exactly, but if we represent the globe more accurately by an ellipsoid model, such as the World Geodetic System 1984 (WGS84), that position shifts slightly. Geographical coordinates can extend from latitude 90 to -90 in the north–south direction, and from longitude -180 to 180 in the east-west direction.

getClass("SpatialPoints")
## Class "SpatialPoints" [package "sp"]
## 
## Slots:
##                                           
## Name:       coords        bbox proj4string
## Class:      matrix      matrix         CRS
## 
## Extends: "Spatial"
## 
## Known Subclasses: 
## Class "SpatialPointsDataFrame", directly
## Class "SpatialPixels", directly
## Class "SpatialPixelsDataFrame", by class "SpatialPixels", distance 2

Indeed, the SpatialPoints class extends the Spatial class by adding a coords slot, into which a matrix of point coordinates can be inserted.

An example (1/2)

Loading a real data set

CRAN_df <- read.table("http://www.asdar-book.org/datasets/CRAN051001a.txt", header = TRUE)
head(CRAN_df)
##            place   north     east       loc      long       lat
## 1       Brisbane 27d28'S 153d02'E Australia 153.03333 -27.46667
## 2      Melbourne 37d49'S 144d58'E Australia 144.96667 -37.81667
## 3           Wien 48d13'N  16d20'E   Austria  16.33333  48.21667
## 4       Curitiba 25d25'S  49d16'W    Brazil -49.26667 -25.41667
## 5      Vi\xe7oza 20d45'S  42d52'W    Brazil -42.86667 -20.75000
## 6 Rio de Janeiro 22d54'S  43d12'W    Brazil -43.20000 -22.90000

We extract the two columns with the longitude and latitude values into a matrix:

CRAN_mat <- cbind(CRAN_df$long, CRAN_df$lat)
row.names(CRAN_mat) <- 1:nrow(CRAN_mat)
str(CRAN_mat)
##  num [1:54, 1:2] 153 145 16.3 -49.3 -42.9 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : chr [1:54] "1" "2" "3" "4" ...
##   ..$ : NULL

An example (2/2)

Creating SpatialPoints class:

crs <- CRS("+proj=longlat +ellps=WGS84")
CRAN_sp <- SpatialPoints(CRAN_mat, proj4string = crs)
summary(CRAN_sp)
## Object of class SpatialPoints
## Coordinates:
##                  min      max
## coords.x1 -122.95000 153.0333
## coords.x2  -37.81667  57.0500
## Is projected: FALSE 
## proj4string : [+proj=longlat +ellps=WGS84 +no_defs]
## Number of points: 54
range(CRAN_mat[, 1])
## [1] -122.9500  153.0333
range(CRAN_mat[, 2])
## [1] -37.81667  57.05000

Some useful functions (1/2)

bbox(CRAN_sp)
##                  min      max
## coords.x1 -122.95000 153.0333
## coords.x2  -37.81667  57.0500
proj4string(CRAN_sp)
## [1] "+proj=longlat +ellps=WGS84 +no_defs"

Some useful functions (2/2)

South_Africa <- which(CRAN_df$loc == "South Africa")
South_Africa
## [1] 34 35
coordinates(CRAN_sp)[South_Africa, ]
##    coords.x1 coords.x2
## 34  18.36667 -33.91667
## 35  26.51667 -33.31667
summary(CRAN_sp[South_Africa, ])
## Object of class SpatialPoints
## Coordinates:
##                 min       max
## coords.x1  18.36667  26.51667
## coords.x2 -33.91667 -33.31667
## Is projected: FALSE 
## proj4string : [+proj=longlat +ellps=WGS84 +no_defs]
## Number of points: 2

SpatialPointsDataFrame class

Data Frames for Spatial Point Data

Here you will see how SpatialPoints object can be taught to behave like a data.frame. To this end, SpatialPointsDataFrame is employed.

getClass("SpatialPointsDataFrame")
## Class "SpatialPointsDataFrame" [package "sp"]
## 
## Slots:
##                                                                   
## Name:         data  coords.nrs      coords        bbox proj4string
## Class:  data.frame     numeric      matrix      matrix         CRS
## 
## Extends: 
## Class "SpatialPoints", directly
## Class "Spatial", by class "SpatialPoints", distance 2
## 
## Known Subclasses: 
## Class "SpatialPixelsDataFrame", directly, with explicit coerce

There are some approaches for reaching to this goal including the following two:

CRAN_spdf1 <- SpatialPointsDataFrame(CRAN_sp, CRAN_df)
CRAN_spdf2 <- CRAN_df
coordinates(CRAN_spdf2) <- CRAN_mat
proj4string(CRAN_spdf2) <- crs

Whether they are equivalent?

all.equal(CRAN_spdf1, CRAN_spdf2)
## [1] TRUE

SpatialLines class

Line \(\longrightarrow\) Lines\(\longrightarrow\) SpatialLines

getClass("SpatialLines")
## Class "SpatialLines" [package "sp"]
## 
## Slots:
##                                           
## Name:        lines        bbox proj4string
## Class:        list      matrix         CRS
## 
## Extends: "Spatial"
## 
## Known Subclasses: "SpatialLinesDataFrame"

Interested readers may refer to Roger et al. (2008, Section 2.5)

SpatialPolygons class

Polygon \(\longrightarrow\) Polygons\(\longrightarrow\) SpatialPolygons

getClass("SpatialPolygons")
## Class "SpatialPolygons" [package "sp"]
## 
## Slots:
##                                                       
## Name:     polygons   plotOrder        bbox proj4string
## Class:        list     integer      matrix         CRS
## 
## Extends: "Spatial"
## 
## Known Subclasses: 
## Class "SpatialPolygonsDataFrame", directly, with explicit coerce

Interested readers may refer to Roger et al. (2008, Section 2.6)

How to import sp data into R?

iran_spdf <- raster::shapefile("iran.shp")
str(iran_spdf, max.level = 2)
## Formal class 'SpatialPolygonsDataFrame' [package "sp"] with 5 slots
##   ..@ data       :'data.frame':  31 obs. of  3 variables:
##   ..@ polygons   :List of 31
##   ..@ plotOrder  : int [1:31] 18 4 15 2 24 25 5 14 20 13 ...
##   ..@ bbox       : num [1:2, 1:2] 44 25.1 63.3 39.8
##   .. ..- attr(*, "dimnames")=List of 2
##   ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
##   ..$ comment: chr "FALSE"
head(iran_spdf@data)
##   Province      Area Cases
## 1      Znj  21782.87    50
## 2      Yzd 128464.45    57
## 3    Azr_q  37392.98    11
## 4      S_B 178850.47    21
## 5      Smn  97192.69   114
## 6      Qom  11513.63   523
bbox(iran_spdf)
##        min      max
## x 44.03878 63.32185
## y 25.06415 39.77122
proj4string(iran_spdf)
## [1] "+proj=longlat +datum=WGS84 +no_defs"

A simple raw map by plot, our old friend!

plot(iran_spdf)

Part II




Creating maps and visualization of spatial data using tmap package



A raw map with the borders

library(tmap)
tm_shape(iran_spdf) +
  tm_borders()

# Remark: In contrary to ggplot2, adding a layer to tm_shape is compulsory! 

A raw map without the borders

library(tmap)
iran_spdf <- sf::st_as_sf(iran_spdf) # The latest version of tamp does not support sp objects. So, we need to convert such objects to sf or tera objects.

tm_shape(iran_spdf) +
  tm_fill()

fill + borders = polygons

tm_shape(iran_spdf) +
  tm_polygons()

Saving maps as objects

map1 <- tm_shape(iran_spdf) +
  tm_fill()
map1

# Remark: ggplot2 has the same property.

Multiple maps on a figure

map1 <- tm_shape(iran_spdf) +
  tm_fill()
map2 <- tm_shape(iran_spdf) +
  tm_borders()
map3 <- tm_shape(iran_spdf) +
  tm_polygons()
tmap_arrange(map1, map2, map3, ncol = 3)

Adding extra layers

tm_shape(iran_spdf) +
  tm_borders() +
  tm_fill()

Spatial distribution of a specific variable

tm_shape(iran_spdf) +
  tm_polygons(fill = "Cases")

# Remark: in contrary to ggplot2, here you can not use iran_spdf$Cases or Cases without quotes!

Spatial distributions of multiple variables

tm_shape(iran_spdf) +
  tm_polygons(fill = c("Cases", "Area"))

# Remark: you will see how we can change the position of the legends.

Modifying the legend style

An arbitrary set of breaks

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", breaks = c(0, 50, 200, 500, 1500))

The quantile legend

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", style = "quantile", n = 4)

quantile(iran_spdf$Cases)
##   0%  25%  50%  75% 100% 
##    5   20   57  145 1234

The continoues legend

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", style = "cont")

Changing the palette

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", style = "cont", palette = "Greens")

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", palette = c("white", "red"))

Reversing palettes

map1 <- tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", style = "cont", palette = "viridis")

map2 <- tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", style = "cont", palette = "-viridis")

tmap_arrange(map1, map2)

Adding labels

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_text("Province", size = 0.7)

Adding second variable as bubbles

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", style = "quantile", n = 4) +
  tm_bubbles(size = "Area", scale = 1.5, col = "white")

Faceting

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_facets(by = "Province")

Adding points to a map

The cities_df: The coordinates of Iran’s cities

library(data.table)
cities_df <- fread("Iran-Cities.csv", data.table = F)[6:5]
names(cities_df) <- c("longitude", "latitude")
str(cities_df)
## 'data.frame':    1132 obs. of  2 variables:
##  $ longitude: num  48.3 47.4 48.6 48.3 47.9 ...
##  $ latitude : num  38.2 39.4 38.3 39.4 39.6 ...
plot(iran_spdf)
points(cities_df)

Converting cities_df to a SpatialPoints object

crs <- CRS("+proj=longlat +datum=WGS84")
crs
## Coordinate Reference System:
## Deprecated Proj.4 representation: +proj=longlat +datum=WGS84 +no_defs 
## WKT2 2019 representation:
## GEOGCRS["unknown",
##     DATUM["World Geodetic System 1984",
##         ELLIPSOID["WGS 84",6378137,298.257223563,
##             LENGTHUNIT["metre",1]],
##         ID["EPSG",6326]],
##     PRIMEM["Greenwich",0,
##         ANGLEUNIT["degree",0.0174532925199433],
##         ID["EPSG",8901]],
##     CS[ellipsoidal,2],
##         AXIS["longitude",east,
##             ORDER[1],
##             ANGLEUNIT["degree",0.0174532925199433,
##                 ID["EPSG",9122]]],
##         AXIS["latitude",north,
##             ORDER[2],
##             ANGLEUNIT["degree",0.0174532925199433,
##                 ID["EPSG",9122]]]]
cities_spp <- SpatialPoints(cities_df, proj4string = crs)
cities_spp
## class       : SpatialPoints 
## features    : 1132 
## extent      : 44.15311, 62.70073, 25.29452, 39.64579  (xmin, xmax, ymin, ymax)
## crs         : +proj=longlat +datum=WGS84 +no_defs
sf::st_bbox(iran_spdf)
##     xmin     ymin     xmax     ymax 
## 44.03878 25.06415 63.32185 39.77122
sf::st_bbox(cities_spp)
##     xmin     ymin     xmax     ymax 
## 44.15311 25.29452 62.70073 39.64579

Adding points to a blank map

# First we should convert cities_spp object to an sf or tera object.

cities_spp <- sf::st_as_sf(cities_spp)

tm_shape(iran_spdf) +
  tm_polygons() +
  tm_shape(cities_spp) +
  tm_dots()

# Remark: In contrary to ggplot2, here you should employ the tm_shape() once again if you want to change the data source.

Adding points to a choropleth map

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_shape(cities_spp) +
  tm_dots(col = "blue")

The spatial distribution of three variables on a map

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_bubbles(size = "Area") +
  tm_shape(cities_spp) +
  tm_dots(col = "blue")

Adding one more variable!

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_bubbles(size = "Area") +
  tm_facets(by = "Province") +
  tm_shape(cities_spp) +
  tm_dots(col = "blue")

Point-in-polygon operation

Spatial overlay: retrieving the attributes from iran_spdf at locations given by cities_spp

pip <- sf::st_intersection(cities_spp, iran_spdf)


dim(pip)
## [1] 1121    4
head(pip)
## Simple feature collection with 6 features and 3 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: 48.06386 ymin: 36.13613 xmax: 49.22454 ymax: 36.99288
## Geodetic CRS:  +proj=longlat +datum=WGS84 +no_defs
##   Province     Area Cases                  geometry
## 1      Znj 21782.87    50 POINT (49.22454 36.13613)
## 2      Znj 21782.87    50 POINT (48.37194 36.97815)
## 3      Znj 21782.87    50 POINT (48.95617 36.92785)
## 4      Znj 21782.87    50 POINT (48.77853 36.99288)
## 5      Znj 21782.87    50 POINT (48.06386 36.29621)
## 6      Znj 21782.87    50 POINT (49.19539 36.21146)
class(pip)
## [1] "sf"         "data.frame"
library(dplyr)
library(ggplot2)
library(plotly)
count_cities <- pip %>% 
  as_tibble() %>% 
  transmute(Province = Province) %>% 
  group_by(Province) %>% 
  summarise(cities = n())

count_cities %>% 
  arrange(desc(cities))
## # A tibble: 31 × 2
##    Province cities
##    <chr>     <int>
##  1 Isf         100
##  2 Frs          93
##  3 Khr_r        76
##  4 Krm          64
##  5 Khz          62
##  6 Azr_s        58
##  7 Mzn          52
##  8 Gil          51
##  9 Thr          42
## 10 Azr_q        39
## # ℹ 21 more rows
count_cities %>% 
  arrange(cities)
## # A tibble: 31 × 2
##    Province cities
##    <chr>     <int>
##  1 Qom           6
##  2 Alb          15
##  3 Khk          16
##  4 Smn          17
##  5 Khr_s        18
##  6 Znj          18
##  7 Ilm          21
##  8 Khr_j        21
##  9 Ard          24
## 10 Gol          24
## # ℹ 21 more rows

Merging the new dataframe count_cities to the SpatialPolygonsDataFrame iran_spdf

head(iran_spdf)
## Simple feature collection with 6 features and 3 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 44.03878 ymin: 25.06415 xmax: 63.32185 ymax: 39.77122
## Geodetic CRS:  +proj=longlat +datum=WGS84 +no_defs
##   Province      Area Cases                       geometry
## 1      Znj  21782.87    50 POLYGON ((48.33729 37.2415,...
## 2      Yzd 128464.45    57 POLYGON ((57.50605 35.06421...
## 3    Azr_q  37392.98    11 POLYGON ((44.42939 39.49004...
## 4      S_B 178850.47    21 POLYGON ((61.20754 31.43992...
## 5      Smn  97192.69   114 POLYGON ((55.80516 37.31446...
## 6      Qom  11513.63   523 POLYGON ((50.74857 35.09618...
head(count_cities)
## # A tibble: 6 × 2
##   Province cities
##   <chr>     <int>
## 1 Alb          15
## 2 Ard          24
## 3 Azr_q        39
## 4 Azr_s        58
## 5 Bsh          29
## 6 Chr          27
iran_spdf <- merge(iran_spdf, count_cities, by = "Province")
class(iran_spdf)
## [1] "sf"         "data.frame"
iran_spdf
## Simple feature collection with 31 features and 4 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 44.03878 ymin: 25.06415 xmax: 63.32185 ymax: 39.77122
## Geodetic CRS:  +proj=longlat +datum=WGS84 +no_defs
## First 10 features:
##    Province      Area Cases cities                       geometry
## 1       Alb   5833.00   302     15 POLYGON ((50.49693 36.34204...
## 2       Ard  17901.83    40     24 POLYGON ((47.90934 39.65886...
## 3     Azr_q  37392.98    11     39 POLYGON ((44.42939 39.49004...
## 4     Azr_s  45756.70    75     58 POLYGON ((47.36301 39.42653...
## 5       Bsh  22765.52     5     29 POLYGON ((50.20877 30.28699...
## 6       Chr  16304.64    14     27 POLYGON ((49.62089 32.78621...
## 7       Frs 122779.33    81     93 POLYGON ((52.20103 31.67056...
## 8       Gil  14086.49   424     51 POLYGON ((48.58556 38.44509...
## 9       Gol  20205.54   104     24 POLYGON ((55.68318 38.10304...
## 10      Hmd  19329.05    23     27 POLYGON ((48.24969 35.71867...

The last step: Drawing a choropleth map based on cities variable

tm_shape(iran_spdf) +
  tm_polygons(col = "cities", title = "Number of cities") +
  tm_bubbles(size = "Cases")

Customization

Changing the background

map1 <- tm_shape(iran_spdf) +
  tm_polygons(col = "cities") +
  tm_style("albatross")
map2 <- tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_style("natural")
map3 <- tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_style("cobalt")
map4 <- tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_style("gray")
tmap_arrange(map1, map2, map3, map4, ncol = 4)

Adding a logo, a scale bar and a compass

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases") +
  tm_text("Province", size = 0.7) +
  tm_logo("R_logo.png", position = c("right", "top")) +
  tm_scale_bar(position = c("center", "bottom")) +
  tm_compass(position = c("center", "top"), size = 2)

Managing titles and legends

map1 <- tm_shape(iran_spdf) +
  tm_polygons(fill = "cities")

map2 <- tm_shape(iran_spdf) +
  tm_borders(col = "white") +
  tm_fill(
    col = "cities",
    title = "Number of cities",
    legend.hist = TRUE,
    legend.hist.title = "Non-Spatial distribution"
  ) +
  tm_compass(position = c("right", "top")) +
  tm_layout(
    main.title = "Iran map",
    title = "Spatial distribution of cities",
    title.bg.color = "yellow",
    bg.color = "gray90",
    frame = FALSE,
    compass.type = "8star",
    legend.hist.bg.color = "white",
    legend.hist.height = 0.15,
    scale = 0.7
  )

tmap_arrange(map1, map2)

Creating interactive maps

tmap_mode("view")
tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", style = "quantile", n = 4)

Modifying the tranparency

tm_shape(iran_spdf) +
  tm_polygons(col = "Cases", style = "quantile", n = 4, alpha = 0.2) +
  tm_shape(cities_spp) +
  tm_dots(col = "red", size = 0.01) +
  tm_markers()

Adding markers

tm_shape(iran_spdf) +
  tm_borders() +
  tm_shape(cities_spp) +
  tm_markers()

Back to static setting

tmap_mode("plot")
tm_shape(iran_spdf) +
  tm_borders() +
  tm_shape(cities_spp) +
  tm_dots()

# Using tm_markers() in the "plot" mode is not recommended!

Part III




Creating maps and visualization of spatial data using ggplot2 package



Creating maps using ggplot2 based on sf objects

library(ggplot2)
ggplot(data = iran_spdf) +
  geom_sf()

Remark: tmap also works based on sf objects

tm_shape(iran_spdf) +
  tm_polygons()

Adding points

ggplot(data = iran_spdf) +
  geom_sf() +
  geom_point(data = cities_df, aes(longitude, latitude))

Modifying crs and the limits of x-y axis

ggplot(data = iran_spdf) +
  geom_sf() +
  geom_point(data = cities_df, aes(longitude, latitude)) +
  coord_sf()

Adding labels (1/2)

ggplot(data = iran_spdf) +
  geom_sf() +
  geom_sf_text(aes(label = Province), size = 2)

Adding labels (2/2)

ggplot(data = iran_spdf) +
  geom_sf() +
  geom_sf_label(aes(label = Province), size = 2, col = "red")

Spatial distribution of a specific variable

ggplot(data = iran_spdf, aes(fill = Cases)) +
  geom_sf()

Modifying the palette (1/2)

library(viridis)
ggplot(data = iran_spdf, aes(fill = Cases)) +
  geom_sf(alpha = 0.5) +
  scale_fill_continuous(type = "viridis", direction = -1)

# or equivalently we can use  `scale_fill_viridis(direction = -1)`

Modifying the palette (2/2)

ggplot(data = iran_spdf, aes(fill = Cases)) +
  geom_sf() +
  scale_fill_gradient(low = "white", high = "red")

Converting a ggplot2 map to a plotly one

map <- ggplot(data = iran_spdf, aes(fill = Cases)) +
  geom_sf() +
  scale_fill_gradient(low = "white", high = "red") +
  geom_sf_text(aes(label = Province), size = 2)

library(plotly)
ggplotly(map)

More customization

For more customization on maps created by ggplot2, refere to the following slide:


https://mahdisalehi.shinyapps.io/Modern_Data_Visualization

Part IV




Creating maps and visualization of spatial data using

  • leaflet
  • mapdeck
  • mapview
  • rayshader
  • plotly



Refrences

[1] Bivand, R.S.; Pebesma E; Gómez-Rubio, V. (2013). Applied Spatial Data Analysis with R (Use R!). Springer; 2nd Edition.

[2] Hijmans, R. J. and Ghosh, A. (2019). Spatial Data Analysis with R (lecture note)

[3] Tennekes M (2018). “tmap: Thematic Maps in R.” Journal of Statistical Software, 84(6), 1-39. doi: 10.18637/jss.v084.i06 (URL: https://doi.org/10.18637/jss.v084.i06).

[4] H. Wickham (2016). ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York.

A guide to R programming for beginners and experienced users (in Persian)
https://www.dibagaranpakhsh.ir/index.php?route=product/product&product_id=1489

Spatial data visualization using tmap and ggplot2 (the current slide):
https://mahdisalehi.shinyapps.io/Spatial_Data_Visualization

Data visualization using ‘ggplot2’ package:
https://mahdisalehi.shinyapps.io/Modern_Data_Visualization

A quick tour to R-Shiny:
https://mahdisalehi.shinyapps.io/shiny

A synergetic R-Shiny portal for modeling and tracking of COVID-19 data:
https://mahdisalehi.shinyapps.io/covid19dashboard