
Creating a simple movement animation
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)