Skip to contents

First, load the required packages for this example and the moveVis example movement data:

move_data is a move2 data frame, containing three individual tracks. moveVis works with such move2 class objects. If your movement data are represented by other classes, e.g. non-spatial data.frames, see ?move2::mt_as_move2 on how to coerce your data into move2 class objects.

Let’s have a look at both timestamps and sampling rates of move_data:

unique(mt_time(move_data))
mt_time_lags(move_data, unit = "min")

You can see 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, fixed regular frame times are needed, regardless whether you want to animate a single track or multiple tracks at once. Thus, we need to align move_data in order to

  • make all tracks share a unique time interval that can be matched by frame times
  • make all tracks share a fixed sampling rate without gaps

To achieve the above, we need to apply interpolation. There are many ways to spatio-temporally interpolate movement tracks. One basic approach to this is linear referencing, as implemented via align_move(). You can use align_move to align movement tracks to a fixed uniform time scale of e.g. 4 minutes:

move_data <- align_move(move_data, res = units::set_units(4, "min"))

Instead, you could apply your own functions for aligning your data, e.g. using more advanced interpolation methods.

Now, as 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 base map imagery or choose from default map types provided by the basemaps package. Here is a GIF of some example base maps you can use out of the box:

You can display a list of all available maps like this:

# get a list of all available map_services and map_types
get_maptypes(as_df = TRUE)
#>          map_service                              map_type
#> 1                osm                               streets
#> 2                osm                            streets_de
#> 3                osm                           topographic
#> 4         osm_stamen                                 toner
#> 5         osm_stamen                              toner_bg
#> 6         osm_stamen                               terrain
#> 7         osm_stamen                            terrain_bg
#> 8         osm_stamen                            watercolor
#> 9         osm_stadia                        alidade_smooth
#> 10        osm_stadia                   alidade_smooth_dark
#> 11        osm_stadia                              outdoors
#> 12        osm_stadia                            osm_bright
#> 13 osm_thunderforest                                 cycle
#> 14 osm_thunderforest                             transport
#> 15 osm_thunderforest                             landscape
#> 16 osm_thunderforest                              outdoors
#> 17 osm_thunderforest                        transport_dark
#> 18 osm_thunderforest                                spinal
#> 19 osm_thunderforest                               pioneer
#> 20 osm_thunderforest                          mobile_atlas
#> 21 osm_thunderforest                         neighbourhood
#> 22 osm_thunderforest                                 atlas
#> 23             carto                                 light
#> 24             carto                       light_no_labels
#> 25             carto                     light_only_labels
#> 26             carto                                  dark
#> 27             carto                        dark_no_labels
#> 28             carto                      dark_only_labels
#> 29             carto                               voyager
#> 30             carto                     voyager_no_labels
#> 31             carto                   voyager_only_labels
#> 32             carto                  voyager_labels_under
#> 33            mapbox                               streets
#> 34            mapbox                              outdoors
#> 35            mapbox                                 light
#> 36            mapbox                                  dark
#> 37            mapbox                             satellite
#> 38            mapbox                                hybrid
#> 39            mapbox                               terrain
#> 40              esri                      natgeo_world_map
#> 41              esri                         usa_topo_maps
#> 42              esri                         world_imagery
#> 43              esri                    world_physical_map
#> 44              esri                   world_shaded_relief
#> 45              esri                      world_street_map
#> 46              esri                    world_terrain_base
#> 47              esri                        world_topo_map
#> 48              esri                  world_dark_gray_base
#> 49              esri             world_dark_gray_reference
#> 50              esri                 world_light_gray_base
#> 51              esri            world_light_gray_reference
#> 52              esri                  world_hillshade_dark
#> 53              esri                       world_hillshade
#> 54              esri                      world_ocean_base
#> 55              esri                 world_ocean_reference
#> 56              esri                     antarctic_imagery
#> 57              esri                        arctic_imagery
#> 58              esri                     arctic_ocean_base
#> 59              esri                arctic_ocean_reference
#> 60              esri world_boundaries_and_places_alternate
#> 61              esri           world_boundaries_and_places
#> 62              esri               world_reference_overlay
#> 63              esri                  world_transportation
#> 64              esri                delorme_world_base_map
#> 65              esri               world_navigation_charts
#> 66          maptiler                             aquarelle
#> 67          maptiler                        aquarelle_dark
#> 68          maptiler                       aquarelle_vivid
#> 69          maptiler                              backdrop
#> 70          maptiler                                 basic
#> 71          maptiler                                bright
#> 72          maptiler                               dataviz
#> 73          maptiler                             landscape
#> 74          maptiler                                 ocean
#> 75          maptiler                               outdoor
#> 76          maptiler                             satellite
#> 77          maptiler                               streets
#> 78          maptiler                                 toner
#> 79          maptiler                                  topo
#> 80          maptiler                                winter

Currently, you can use more than 75 types of maps, e.g. provided by OpenStreetMap, Carto or Mapbox. For some map services, you need a (free) map token for which you need an account at the respective service (see supported maps<> for details).

In this example, we want to use the OpenStreetMap ‘topographic’ imagery with a transparency of 50% to standard with a fairly standard type of map. To create a spatial frames from move_data using a base map, we can use frames_spatial() like this:

frames <- frames_spatial(move_data, path_colours = c("red", "green", "blue"),
                         map_service = "osm", map_type = "topographic", alpha = 0.5)

Instead of using path_colours, you can add a colour column to your move2 object. This allows you to colour your movement tracks as you want, e.g. not only by individual track, but by behavioural segment, time, age, speed or something different (see ?frames_spatial for details).

Have a look at the newly created frames object. You can retrieve some information about the frames that you have just created and plot individual frames to get first impressions on how your animation will look like:

frames
#> moveVis frames (spatial), ≈ 7.52s at 25 fps using 188 frames
#> Temporal extent:  2018-05-15 07:03:59.636288 to 2018-05-15 19:31:59.636288
#> Spatial extent:   xmin: 990463.40648; ymin: 6060710.02464; xmax: 1001881.32133; ymax: 6069317.35905
#> CRS (projected):  WGS 84 / Pseudo-Mercator
#> Basemap:          'topographic' from 'osm'
#> Names:            'T932u', 'T342g', 'T246a'

length(frames) # number of frames
#> [1] 188
frames[[100]] # display one of the frames

You can pass any moveVis frames object 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 right away. If you are not sure, which output formats can be used, run suggest_formats(). This function returns a vector of file suffixes that can be created on your operating system. For making a GIF from frames, just run:

animate_frames(frames, out_file = "example_1.gif")

We have just used a classic OpenStreetMap map as base map. You can try different map services and types (some of which are showcased as visual examples in the basemaps documentation):

frames <- frames_spatial(move_data, path_colours = c("red", "green", "blue"),
                         map_service = "carto", map_type = "light", map_res = 0.8)
frames[[100]] # display one of the frames

Like above, these frames can be put in motion using animate_frames():

animate_frames(frames, out_file = "example_1b.gif")

That’s the basics of using moveVis! If you want to learn more, take a look at how moveVis frames can be customized – either using the moveVis add_ functions or by applying ggplot2 code frame-by-frame.