Short moveVis example on how to overlay frames with additional transparent rasters changing over time
library(moveVis) | |
library(move) | |
library(ggplot2) | |
data("move_data", "basemap_data") | |
m <- align_move(move_data, res = 4, unit = "mins") | |
## create frames using mapbox base map | |
frames <- frames_spatial(m, map_type = "satellite", map_service = "mapbox", map_token = "YOUR_VERY_LONG_TOKEN", | |
path_legend = T) | |
r_list <- basemap_data[[1]] | |
r_times <- basemap_data[[2]] | |
# crop to plot extent | |
r_list <- lapply(r_list, raster::crop, y = extent(m), snap = "out") | |
# here I fake a 3 class categorical raster | |
r_list <- lapply(r_list, function(x){ | |
y <- setValues(x, round(getValues(x)*3)) | |
y[y == 0] <- 3 | |
return(y) | |
}) | |
## first, we need a list of rasters with the same length as frames | |
## and with each raster at the correct time in that list. For this: | |
# create timestamps of m | |
ts <- sort(unique(timestamps(m))) | |
# ts has same length as frames, since frames were created from the timestamps of m | |
# caclulate difftime for each time stamp to all time stamps of your rasters and get minimum absolute diff | |
r_pos <- sapply(ts, function(x) which.min(abs(difftime(x, r_times)))) | |
# the subscript with min abs time difference between the raster time and the times of m | |
# is what we used to assign the rasters per time: | |
r_list <- lapply(r_pos, function(i) r_list[[i]]) | |
# now, rasters are assigned per frame time | |
## just call add_gg with a ggplot2 raster drawing command, | |
# for example the ggR function in RStoolbox in the layer mode with 30 % opacity: | |
frames_overlayed <- add_gg(frames, gg = expr(RStoolbox::ggR(data, alpha = 0.8, forceCat = T, ggLayer = T)), data = r_list) | |
# iterates over all frames and over r_list (same lengths) and applies the ggR function | |
# instead of ggR, you could use any ggplot2 expression you like to create a raster layer | |
frames_overlayed[[100]] | |
# or if you want so specify colours and alpha per class ( e.g. make a class be completely transparent), | |
# you can use geom_raster. | |
# turn r_list into data.frames for ggplot2 and define colours and alphas per value (here we have 3 classes) | |
r_df <- lapply(r_list, function(x) data.frame(coordinates(x), | |
vals = values(x), | |
cols = plyr::mapvalues(values(x), 1:3, c("darkgreen", "green", "blue")), | |
alpha = plyr::mapvalues(values(x), 1:3, c(0, 0.4, 1)))) | |
# and use geom_raster with r_df to get colours and alpha per class | |
frames_overlayed <- add_gg(frames, gg = expr(geom_raster(data = r_df[[100]], mapping = aes(x = x, y = y, fill = cols, alpha = alpha), show.legend = F)), data = r_df) | |
frames_overlayed[[100]] | |
# additional note: | |
# With geom_raster, plot extents are changed, while with ggR using annotation_raster, plot extents remain | |
# so either crop to the correct extent or fixate the ggplot axis limits of frames before adding geom_raster | |
# I did not manage to display a legend for fill of geom_raster and do not know why, but had no time to investigate. | |
# alpha legend is displayed though, if show.legend = T |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment