example-1.Rmd
First, load the required packages for this example and the moveVis
example movement data:
move_data
is a moveStack
, containing three individual tracks. moveVis
works with move
class objects. If your movement tracks are present as data.frames
, see df2move()
and the example code there for conversion. Let’s have a look at both timestamps and sampling rates of move_data
:
unique(timestamps(move_data))
timeLag(move_data, unit = "mins")
We can conclude that each track has a sampling rate of roughly 4 minutes, however sampling rates differ over time. Due to this, tracks do not share unique timestamps. For animation, unique frame times are needed, regardless if we want to animate a single track or multiple at once. Thus, we need to align move_data
in order to * make all tracks share unique timestamps that can be assigned to frames * make all tracks share unique, steady sampling rates without gaps
You can use align_move()
to align move_data
to a sampling rate of 4 minutes:
move_data <- align_move(move_data, res = 4, unit = "mins")
Instead, you could apply your own functions for aligning your data, e.g. using more advanced interpolation methods.
Now, as the movement tracks are aligned, we can pair them with a base map to create frames that can be turned into an animation later on. You can use your own custom base map imagery or choose from default map types. Here is a GIF of some example base maps you can use out of the box thanks to the slippymath
package:
You can display a list of all available maps:
# get a list of all available map_services and map_types
get_maptypes()`
$osm
[1] "streets" "streets_de" "streets_fr" "humanitarian" "topographic" "roads"
[7] "hydda" "hydda_base" "hike" "grayscale" "no_labels" "watercolor"
[13] "toner" "toner_bg" "toner_lite" "terrain" "terrain_bg" "mtb"
$carto
[1] "light" "light_no_labels" "light_only_labels" "dark"
[5] "dark_no_labels" "dark_only_labels" "voyager" "voyager_no_labels"
[9] "voyager_only_labels" "voyager_labels_under"
$mapbox
[1] "satellite" "streets" "streets_basic" "hybrid" "light"
[6] "dark" "high_contrast" "outdoors" "hike" "wheatpaste"
[11] "pencil" "comic" "pirates" "emerald"
Currently, you can use more than 40 types of maps, provided by OpenStreetMap
, Carto
(both free without registration) and Mapbox
(free, but registration required). Most maps display thematic or terrain data, while Mapbox
also offers satellite imagery (see Example 3: using a mapbox satellite base map for details on how to register and use mapbox).
In this example, we want to use the OpenStreetMap ‘watercolour’ imagery with a transparency of 50% to start with something nice looking and colourful. To create a list of spatial frames from move_data
using a map, we can use frames_spatial()
:
frames <- frames_spatial(move_data, path_colours = c("red", "green", "blue"),
map_service = "osm", map_type = "watercolor", alpha = 0.5)
Instead of using path_colours
, you can add a colour
column to your move
or moveStack
object. This allows you to colour your movement tracks as you want, e.g. not only by individual track, but by behavioral segment, time, age, speed or something different (see ?frames_spatial
for details).
Have a look at the newly created frames
list object and display a randomly selected frame to get a first impression, how your animation will look like:
length(frames) # number of frames
frames[[100]] # display one of the frames
You can pass any list of frames like the one we just created to animate_frames()
. This function will turn your frames into an animation, written as a GIF image or a video file. For now, we do not want to add any customization to frames
and just create a GIF
from it. If you are not sure, which output formats can be used, run suggest_formats()
that returns you a vector of file suffixes that can be created on your system. For making a GIF
from frames
, just run:
animate_frames(frames, out_file = "example_1.gif")
We have just used an OSM
base map that does not contain any map labels. How would the same frames look like with a standard OSM
streets base map?
frames <- frames_spatial(move_data, path_colours = c("red", "green", "blue"),
map_service = "osm", map_type = "streets", map_res = 0.8)
frames[[100]] # display one of the frames
You may recognize that the map seems to be distorted which becomes mainly visible when looking at the map labels. By default, moveVis
calculates an equidistant map extent (squared), with y and x axis measuring equal surface distances. In addition, moveVis
reprojects the default base maps to the projection of your movement data. The default base maps are originally projected as WGS 84 / Pseudo Mercator
(epsg:3857
), also referred to as Web Mercator
, and thus are squeezed or stretched onto the projection grid of the movement data (in this case WGS 84 / LatLon
).
To represent the base map in its original projection, just reproject your movement data to the WGS 84 / Pseudo Mercator
projection and disable the calculation of an equidistant extent:
move_data <- sp::spTransform(move_data, crs("+init=epsg:3857"))
frames <- frames_spatial(move_data, path_colours = c("red", "green", "blue"),
map_service = "osm", map_type = "streets", map_res = 0.8, equidistant = F)
frames[[100]] # display one of the frames
Finally, animate the newly created frames:
animate_frames(frames, out_file = "example_1b.gif", width = 700, height = 500, res = 80)