Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ggplot to plot shapefile and gganimate for animation

Sample data

library(raster)
library(ggplot2)

my.shp <- getData('GADM', country = 'FRA', level = 1)
plot(my.shp)

enter image description here

If I want to plot this data using ggplot:

my.shp_f <- fortify(my.shp, region = "ID_1")
ggplot(data = my.shp_f, aes(long, lat, group = group)) + geom_polygon(fill = "grey80")

enter image description here

Question 1: Why has administrative boundary disappeared?

Question 2: I have another dataframe which has 2 years of daily rainfall data from day 1 to day 365 of for each of the administrative divisions.

rain.data <- data.frame(ID_1 = rep(my.shp@data$ID_1, each = 2 * 365),
                        year = rep(rep(1981:1982, each = 365), times = 2),
                        day = rep(1:365, times = 4),
                        rain = sample(1:20, replace = T, 2 * 365 * 2))

I want to create an animation of daily rainfall for this shape file going from day 1 1981 to day 365 1982.

My overall approach at the moment is to make a loop and save rainfall map of each day as individual .png file and then stack those files as .gif. However, this results in me saving 2 years X 365 days worth of .png files first and then stack them together. If I have 30 years worth of data, this becomes impossible. I read this post about gganimate https://github.com/thomasp85/gganimate and wondered if someone can demonstrate how to generate an animated map using gganimate using the data above

like image 200
89_Simple Avatar asked Aug 24 '18 15:08

89_Simple


Video Answer


1 Answers

This answer is steering things a little bit in a different direction but I've wanting to try gganimate and this was a good excuse. My modifications are primarily by using the sf package and the new geom_sf Geom from ggplot2. I don't love the hacky date fixing so that certainly could be improved. I also only plotted a subset of the Dates - the amount of data you have will likely take some time depending on your setup. Anyways here is what I would do:

library(raster)
library(ggplot2)
library(sf)
library(dplyr)
library(lubridate)
library(gganimate)
library(rmapshaper)

my.shp <- getData('GADM', country = 'FRA', level = 1)

## Convert the spatial file to sf
my.shp_sf <- st_as_sf(my.shp) %>% 
  ms_simplify()

## Here is how to plot without the rain data
ggplot(my.shp_sf) +
  geom_sf()

## Convert your data into a date
## this is very hacky and coule be improved
rain.data <- data.frame(ID_1 = rep(my.shp@data$ID_1, each = 2 * 365),
                        year = rep(rep(1981:1982, each = 365), times = 2),
                        day = rep(1:365, times = 4),
                        rain = sample(1:20, replace = T, 2 * 365 * 2)) 

date_wo_year <- as.Date(rain.data$day -1, origin = "1981-01-01")
rain.data$Date = ymd(paste0(rain.data$year, "-",month(date_wo_year),"-", day(date_wo_year)))

## Join the rain.data with a properly formatted date with the spatial data. 
joined_spatial <- my.shp_sf %>% 
  left_join(rain.data)

## Plot the spatial data and create an animation
joined_spatial %>% 
  filter(Date < as.Date("1981-02-28")) %>% 
  ggplot() +
  geom_sf(aes(fill = rain)) +
  scale_fill_viridis_c() +
  theme_void() +
  coord_sf(datum = NA) +
  labs(title = 'Date: {current_frame}') +
  transition_manual(Date) 
like image 89
boshek Avatar answered Nov 11 '22 15:11

boshek