Animating Markers on Maps — the R Way

Balakrishna Ch
3 min readMay 3, 2022

Let me confess. Python’s gdal package always showed me hell. Because of that single reason, I always use R for any geospatial plotting. So, what’s the background of this? There was this article which I wrote a few years ago. Suddenly, I was thinking, if it is easily possible to plot data on a map and use it as a background for a video. I had a background in R and geospatial data analysis. But, I still wanted to go for python because that’s where I do all my ad hoc coding work. I naturally went to gdal, it created much trouble for me yet again — simply put, I wasted a few hours trying to install it and left it to check how useful R is for my work. And R did the work perfectly — both animated plotting and shapefile manipulation.

The animated plotting video is below. I will accept it’s subpar — my MacBook died and I had to work with whatever I had on Windows. But, I know that’s not an excuse.

So, what’s about the other one, the topic of the article — Animated Maps?

The core packages to use in this case are tidygeocoder, osrm, sf for fetching carving the path, ggmap for the maps and ggplot2 and gganimate to prepare the end result. This piece of code is based on a stackexchange discussion.

The pseudo-code for this goes thus.

What is the route you want to take?

adresses <- c("Berlin", "Gdansk", "Minsk",
"Moscow")

Convert the considered points into coordinates.

data <- tidygeocoder::geo(adresses, method = "osm") %>% 
st_as_sf(coords = c("long", "lat"), crs = 4326)

Convert these points into an integrated path.

osroute <- osrm::osrmRoute(loc = data,
returnclass = "sf")
osroute_sampled <- st_transform(osroute) %>%
st_sample(type = 'regular', size = 50) %>%
st_cast('POINT') %>%
st_as_sf()

Now, convert this data into a readable format. You are just splitting the records into x and y coordinates for plotting

osroute_xy <- osroute_sampled %>% 
mutate(seq = 1:nrow(.),
x = st_coordinates(.)[,"X"],
y = st_coordinates(.)[,"Y"])

Download the maps, animate and download.

BMM <- get_stamenmap(bbox = c(10, 40, 57, 60),
zoom = 6,
maptype = "terrain")

animation <- ggmap(BMM) +
geom_point(data = osroute_xy,
aes(x = x, y = y),
color = "red",
size = 4) +
theme_void() +
transition_reveal(seq) +
shadow_wake(wake_length = 1/6)
gganimate::animate(animation,
nframes = 2*(nrow(osroute_xy)+1),
height = 800,
width = 760,
fps = 10,
renderer = gifski_renderer(loop = T))
gganimate::anim_save('animated_bmm.gif', animation = last_animation())

The only thing which you may want to look at here is what goes inside get_stamenmap. Everything else is intuitive enough.

--

--

Balakrishna Ch

A jack of all trades still trying to understand what he is a master of