RchivalTag Tutorial | Part 4 - Geolocation Estimates and Likelihood Areas

RchivalTag ggplot plotly leaflet oceanmap daytime-shading

In this fourth part of the RchivalTag tutorial series, we will learn how to explore geolocation estimates and related likelihood areas from pop-up archival tags.

Robert K. Bauer http://www2.hawaii.edu/~rkbauer (Hawai’i Institute of Marine Biology
University of Hawai’i at Mānoa)https://scholar.google.com/citations?hl=en&user=J-0_tdbR2tgC
01-10-2021

Principle (Pop-up)-Archival Tagging Data

  1. TAD, TAT plots per individual and all animals, season
  2. PDT plot with depth tracks
  3. time series data (e.g. depth and temperature)
  4. tracks (Geolocation Estimates and Likelihood Areas from light levels, depth and temperature)

Getting started | Requirements

To run this tutorial we will need RchivalTag version >= 0.1.5 and oceanmap version >= 0.13. You can find the newest versions of both packages on github

## install or load package
# install.packages("RchivalTag") # from CRAN
# library(xfun)
# install_github("rkbauer/oceanmap") # newest version from github
# install_github("rkbauer/RchivalTag") # newest version from github
library("RchivalTag")

## Package overview and version:
?RchivalTag 
help(package="RchivalTag") ## list of functions

Wildlife Computers exports 5 different types of tag tracks from their tags: 1. Light level based Geolocation Estimates (Maxmimum Likelihood Tracks) from GPE3 model runs stored in csv-files 2. Likelihood Areas (Probability Maps) from GPE3 model runs stored in netcdf-files 3. Likelihood Areas (Probability Maps) from GPE3 model runs stored in kmz-files (google earth format) 4. ARGOS tracks (e.g. from poped up mk10 tags, miniPATs or surfacing SPLASH tags) 5. Fastloc GPS (from surfacing SPLASH-F tags)

RchivalTag comes with a functions to read in and plot tag tracks from the different file formats (currently supported are Maxmimum Likelihood Tracks, Likelihood Areas from netcdf- and kmz-files).

1) How to read in and plot Maxmimum Likelihood Tracks

## example 1a) scatter plot from csv-file:
csv_file <- system.file("example_files/15P1019-104659-1-GPE3.csv",package="RchivalTag")
pos <- get_geopos(csv_file) ## show tracks as line plot
Loading tagging tracks from file: /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P1019-104659-1-GPE3.csv
ggplot_geopos(pos) ## shows Maxmimum Likelihood tracks as scatter plot

We can speed this up by running the ggplot_geopos() function directly on the csv-file:

## same result by direct run with ggplot_geopos()
ggobj1 <- ggplot_geopos(csv_file)
ggobj1

We can also add the track to an existing ggplot-object (with flipped colorbar):

library(oceanmap)
ggobj_tmp <- ggplotmap("lion")
ggobj2 <- ggplot_geopos(csv_file,ggobj = ggobj_tmp, cb.reverse = FALSE)
ggobj2

By default, ggplot_geopos() adds the tracks to a ggplot-object generated by the ggplotmap()-function from the oceanmap-package. This function comes with a lot of options to select the plotting region and style (grid, scale frame, etc.) Since the result of ggplot_geopos() is also a ggplot-object, we can adjust it like any other ggplot object to our wishes. Please refer to the oceanmap tutorial as well as the ggplotmap()-help file for further examples and options.

ggobj_tmp <- ggplotmap("lion",grid=F,bwd=0,ticklabels = F)
ggobj2 <- ggplot_geopos(csv_file, ggobj = ggobj_tmp)
ggobj2

You can also add (most of) the ggplotmap-arguments to the ggplot_geopos() call.

ggobj <- ggplot_geopos(csv_file,grid=F,bwd=0,xlim = c(2,9),ylim=c(39,44))
ggobj

However, you can also use another ggplot object as base map, as the following more manual approach illustrates.

library("tidyverse")
library("mapview")
library("sf")
library("rnaturalearth")
library("rnaturalearthdata")
library("ggspatial")

world <- rnaturalearth::ne_countries(scale = 'small', returnclass = 'sf')

world  <- st_cast(world, 'MULTILINESTRING') %>%
  st_cast('LINESTRING', do_split=TRUE) %>%
  mutate(npts = npts(geometry, by_feature = TRUE)) %>%
  st_cast('POLYGON')

world <- ne_countries(scale = "medium", returnclass = "sf")

ggobj <- ggplot(data = world) +
  geom_sf() +
  annotation_scale(location = "bl", width_hint = 0.5) + ## add scale bar
  annotation_north_arrow(location = "bl", which_north = "true", 
                         pad_x = unit(0.75, "in"), pad_y = unit(0.5, "in"),
                         style = north_arrow_fancy_orienteering) + ## add compass
  coord_sf(xlim = c(0,10), ylim = c(38,45), expand = FALSE) + theme_minimal()

# Now let's add our track:
csv_file <- system.file("example_files/15P1019-104659-1-GPE3.csv",package="RchivalTag")
ggobj2 <- ggplot_geopos(csv_file,ggobj = ggobj)
ggobj2

We can show the track as a line, or a dotted line and combine tracks:

# ## load second file:
csv_file2 <- system.file("example_files/14P0911-46177-1-GPE3.csv",package="RchivalTag")
pos2 <- get_geopos(csv_file2)  ## show tracks as line plot
Loading tagging tracks from file: /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/14P0911-46177-1-GPE3.csv
ggobj2 <- ggplot_geopos(pos2,type = "l")
ggobj2 ## line plot

ggplot_geopos(rbind(pos,pos2),type = "b")

We can also colorize the tracks by ID instead of date.

library(ggplot2)
ggplot_geopos(rbind(pos,pos2),color_by = "DeployID")

# combine tracks:
library(oceanmap)
ggobj <- ggplotmap(lon = c(-6.0, 16.5), lat=c(34.0, 44.5))
ggobj2 <- ggplot_geopos(pos,ggobj = ggobj)
ggobj2tracks <- ggplot_geopos(pos2,ggobj = ggobj2,zlim=range(c(pos$date,pos2$date))) # not working
ggobj2tracks

pos3 <- rbind(pos,pos2)
ggobj3a <- ggplot_geopos(pos3,type = "l")
ggobj3a
ggobj3b <- ggplot_geopos(pos3,type = "b")
ggobj3b
# ggobj3c <- ggplot_geopos(pos3,type = "p")
# ggobj3c
## example 1b) scatter plot from csv-file on existing landmask:
ggobj <- oceanmap::ggplotmap('lion',grid.res = 5) # use keyword to derive area limits
ggobj4 <- ggplot_geopos(csv_file,ggobj)
ggobj4
# ## alternatives:
# pos <- get_geopos(csv_file)
# r <- oceanmap::regions("lion")
# ggobj4b <- ggplot_geopos(pos, xlim = r$xlim, ylim = r$ylim)
# ggobj4b

ggplot_geopos with netcdf-files:

Each GPE3 model run returns also the probability surfaces of our tracks. They are more accurate to illustrate the error of the data. We can read and visualize them as well with the ggplot_geopos-function from RchivalTag.

## example 2) probability surfaces of horizontal tracks from nc-file:
## this can take some time as it inlcudes time consuming data processing
nc_file <- system.file("example_files/15P1019-104659-1-GPE3.nc",package="RchivalTag")
ggobj6 <- ggplot_geopos(nc_file)
ggobj6

# ## alternative:
# pols_df <- get_geopos(nc_file)
# ggplot_geopos(pols_df)

ggplot_geopos with kmz-files

Another much faster way to plot the probability surfaces of your tag’s track is to read in kmz-file which already includes the contour lines of the 50, 95 and 99% likelihood areas that are being extracted and likewise transformed to a SpatialPolygonsDataFrame. This is much faster than the netcdf-transformation process. However, the kmz-files from WC include only a subsample (up to 50) of the GPE3 likelihood areas. The use of these files is therefore only recommended for visualization purposes. Please contact WC if you are looking for a kmz-file with the complete GPE3 likelihood areas or use the netcdf-file transformation instead.

## example 3) probability surfaces of horizontal tracks from kmz-file:
kmz_file1 <- system.file("example_files/15P1019-104659-1-GPE3.kmz",package="RchivalTag")
ggobj7 <- ggplot_geopos(kmz_file1)
ggobj7

kmz_file2 <- system.file("example_files/15P0986-15P0986-2-GPE3.kmz",package="RchivalTag")
ggobj8 <- ggplot_geopos(kmz_file2)
ggobj8

k1 <- get_geopos(kmz_file1)
Loading tagging tracks from file: /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P1019-104659-1-GPE3.kmz
extracted kml-file from provided kmz-file
k2 <- get_geopos(kmz_file2)
Loading tagging tracks from file: /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P0986-15P0986-2-GPE3.kmz
extracted kml-file from provided kmz-file

k3 <- rbind(k1,k2)
ggobj9 <- ggplot_geopos(k3)
ggobj9

Extend the plotting region

ggobj9b <- ggplot_geopos(k3,ggobj = ggplotmap("lion"))
ggobj9b

ggobj <- ggplotmap("mednw4")
## p1 <- ggplot_geopos(k1,ggobj = ggobj) ## not working, need to change date format:
# k2$datetime <- k2$datetime+90*24*60*60
p1 <- ggplot_geopos(k1,grid.res=1)
p1
p2 <- ggplot_geopos(k2,p1,zlim = as.Date(range(c(k1$datetime,k2$datetime))))#,
p2

ggplot_geopos with base maps

We can also add a reference layer such as the bathymetry and illustrate our tracks on top. Instead of the maxmimum likelihood tracks from the csv file you can also plot the maximum likelihood aread from kmz- or netcdf-files (see examples below). In this case you will need to add the new_scale_fill() call when creating the bathymetry-basemap for your tracks. However, a ggplotly-transformation (see next section) is so far only implemented for basemaps with point data (maxmimum likelihood tracks) and not supported yet for polygon data with a basemap yet.

library(oceanmap)
library(dplyr)
library(ggplot2)
library(ggnewscale)
data(cmap)
h <- get.bathy(v_area = "lion",visualize = F) ## from the oceanmap package
## note that you can also define lon and lat limits to specify your area of interest
rs2df <- h %>% rasterToPoints() %>% ## convert raster to xyz matrix
         as.data.frame() ## convert to data frame
names(rs2df) <- c("Lon","Lat","Depth") ## reset names 
ggobj <- ggplot() + geom_raster(data = rs2df, aes(x=Lon,y=Lat,fill=Depth)) 
ggobj_with_bathy <- ggplotmap(add_to = ggobj) + 
                        scale_fill_gradientn(colours=cmap$haxbyrev,limits=range(rs2df$Depth)) # change colorbar  
                        #+ new_scale_fill() # allow additional fill scale in case of polygon illustrations of maximum likelihood areas from kmz- or netcdf-files
ggobj_with_bathy_and_tracks <- ggplot_geopos(csv_file,ggobj = ggobj_with_bathy)
ggobj_with_bathy_and_tracks

plotly visualizations with RchivalTag

And we can transform the ggplot visualizations of our tracks to an interactive plotly-figure. (ATTENTION: Due to computational restrictions the ggplot object includes only islands and countries that are shown in the plotting region. It is therefore not recommended to zoom out of this region in the plotly widget. Click the home button if that is the case. A request to limit the zoom area to the axis boundaries of the has been launched to the plotly-developers. Once this has been implemented the function will be updated.

ggplotly_geopos(ggobj1) # dot plot
# ggplotly_geopos(ggobj2) # line plot
# ggplotly_geopos(ggobj3b) # combined tracks
# ggplotly_geopos(ggobj9b) # polygons

We can also convert this to an interactive plot, but may need to define a larger area when downloading the bathymetry in order not to cut it. This works properly for point data but not for polygons with reference map (i.e. bathymetry)

# ggplotly_geopos(ggobj_with_bathy_and_tracks)
## 


leaflet visualizations with RchivalTag

csv_file <- system.file("example_files/15P1019-104659-1-GPE3.csv",package="RchivalTag")
pos <- get_geopos(csv_file) ## show tracks as line plot
Loading tagging tracks from file: /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P1019-104659-1-GPE3.csv
leaflet_geopos(pos,ID_label="DeployID",collapsedLayers = T) 
# leaflet_geopos(pos,ID_label="DeployID",showSlideBar = T)
kmz_file <- system.file("example_files/15P1019-104659-1-GPE3.kmz",package="RchivalTag")
k1 <- get_geopos(kmz_file)
Loading tagging tracks from file: /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P1019-104659-1-GPE3.kmz
extracted kml-file from provided kmz-file
kmz_file2 <- system.file("example_files/15P0986-15P0986-2-GPE3.kmz",package="RchivalTag")
k2 <- get_geopos(kmz_file2)
Loading tagging tracks from file: /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P0986-15P0986-2-GPE3.kmz
extracted kml-file from provided kmz-file
k0 <- k3 <- rbind(k1,k2)

library(leaflet)
leaflet_geopos(k0,ID_label="DeployID",collapsedLayers = F)
leaflet_geopos(k0,ID_label="DeployID",showSlideBar = T)

We can add further functionalities to the leaflet map, such as a mini map to illustrate the zoom area.

k1$ID <- "12"
k1$Serial <- k1$DeployID <- c() # delete Serial field

map <- leaflet_geopos(k1,ID_label="ID")  %>% addMiniMap( position = "bottomleft")
map

More extensions are provided by the leaflet.extras and leaflet.extras2 packages.

library(leaflet.extras)
map <- update_leaflet_elementId(map) ## this is required to avoid rendering issues when plotting the same map twice via RMarkdown 
map %>% addMeasure(position = "bottomleft", primaryLengthUnit = "meters", #primaryAreaUnit = "hectares", 
                   activeColor = "#3D535D", completedColor = "#7D4479", localization = "en", popupOptions = list(autoClose = FALSE,latlngFormat = "DD")) %>% 
  addSearchOSM(options = searchOptions(autoCollapse = TRUE, minLength = 2, hideMarkerOnCollapse = TRUE, moveToLocation = TRUE, zoom = 14))

How to integrate geolocation estimates with your time series data

# combine geolocation estimates with the time series data:
ts_file <- system.file("example_files/104659-Series.csv",package="RchivalTag")
ts_df <- read_TS(ts_file)
head(ts_df,2)
  DeployID    Ptt       date            datetime DepthSensor Source
1  15P1019 104659 2016-08-07 2016-08-07 00:00:00          NA   <NA>
2  15P1019 104659 2016-08-07 2016-08-07 00:05:00          NA   <NA>
  Instr Depth DRange Temperature TRange
1  <NA>    NA     NA          NA     NA
2  <NA>    NA     NA          NA     NA
pos <- get_geopos(csv_file)
Loading tagging tracks from file: /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P1019-104659-1-GPE3.csv
head(pos,2)
  DeployID    Ptt    Lat   Lon Observation.Type Observed.SST
1  15P1019 104659 43.125 5.175             User           NA
2  15P1019 104659 43.125 5.200             None           NA
  Satellite.SST Observed.Depth Bathymetry.Depth Observation.LL..MSS.
1            NA             NA               NA                   NA
2            NA             NA               NA                   NA
  Observation.Score Sunrise Sunset
1          52.31076               
2                NA               
                                                                                             file
1 /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P1019-104659-1-GPE3.csv
2 /home/work/R/x86_64-pc-linux-gnu-library/3.6/RchivalTag/example_files/15P1019-104659-1-GPE3.csv
   Serial               speed score            datetime       date
1 15P1019 75.0 kilometers/day 42.82 2016-08-07 08:00:00 2016-08-07
2 15P1019 75.0 kilometers/day 42.82 2016-08-07 12:00:00 2016-08-07

library(plyr)
input <- pos[,c("date","Lon","Lat")]
add <- ddply(input,.(date),function(x) c(Lon=mean(x$Lon),Lat=mean(x$Lat)))
out <- merge(ts_df,add,by="date")
out <- out[order(out$datetime),]

out <- classify_DayTime(out) # define daytime periods
plot_DepthTS(out,plot_DayTimePeriods = T)

References

Citation

For attribution, please cite this work as

Bauer (2021, Jan. 10). Marine Biologging & Data Science | Blog: RchivalTag Tutorial | Part 4 - Geolocation Estimates and Likelihood Areas. Retrieved from http://oceantags.com/posts/RchivalTag_Tutorials_Part4_Geolocations/

BibTeX citation

@misc{bauer2021rchivaltag,
  author = {Bauer, Robert K.},
  title = {Marine Biologging & Data Science | Blog: RchivalTag Tutorial | Part 4 - Geolocation Estimates and Likelihood Areas},
  url = {http://oceantags.com/posts/RchivalTag_Tutorials_Part4_Geolocations/},
  year = {2021}
}