This is a wrapper function for plot_ly which streamlines the production of 3d, interactive raster plots. Key features include (a) automated handling of raster orientation and appropriate labelling, (b) internal aggregation of large rasters, if requested, (c) zooming around inputted points, if requested, (d) the addition of coastlines to 3d rasters, if requested, and (e) additional control over plot shape. Points (e.g. passive acoustic telemetry receivers) and lines (e.g. movement pathways) can be added across the landscape. Some other plot_ly options are also supported. This function was motivated by the need to visualise rapidly a complex bathymetric landscape with passive acoustic telemetry receivers and reconstructed animal movement pathways over the seabed.

pretty_scape_3d(
  r,
  aggregate = NULL,
  add_surface = list(colors = grDevices::heat.colors(100)),
  add_markers = NULL,
  thin_markers = FALSE,
  buffer = NULL,
  add_paths = NULL,
  coastline = NULL,
  coastline_paths = list(line = list(color = grDevices::rgb(0, 0, 0), width = 4)),
  plane = NULL,
  plane_surface = list(showscale = FALSE),
  xlim = NULL,
  ylim = NULL,
  zlim = NULL,
  add_tick_text = TRUE,
  font = list(family = "sans", size = 18, color = "black"),
  xtitle = "",
  ytitle = "",
  ztitle = "",
  stretch = 1,
  aspectmode = "cube",
  eye = list(),
  verbose = TRUE,
  ...
)

Arguments

r

A raster to be plotted. The raster should be less than, approximately, 1800 x 1800 cells (otherwise, plot_ly will not show the plot). Raster aggregation can be implemented within the function (see aggregate, below), although this may be slow for large rasters. Interactive plots of lower resolution rasters are more responsive.

aggregate

(optional) A named list of arguments that is passed to aggregate to aggregate raster cells. If provided, the raster, r, is aggregated within the function prior to plotting. For large rasters, this is necessary to reduce raster dimension to a size which can be handled by plot_ly, which creates the underlying plot. The raster can also be reduced in size by zooming around points provided (see buffer).

add_surface

(optional) A named list of arguments that is passed to add_surface to customise the raster surface added to the plot.

add_markers

(optional) A named list of arguments that is passed to add_markers to add points to the plot.

thin_markers

(optional) A logical input which defines whether or not plot all inputted markers (thin_markers = FALSE) or only those markers that fall within the domain of the raster (thin_markers = TRUE).

buffer

(optional) A named list of arguments that is passed to gBuffer to add a buffer around inputted points, provided via add_markers, below (e.g. buffer = list(width = 1)). If provided, only the raster cells which fall into this/these buffer(s) are shown.

add_paths

(optional) A named list of arguments that is passed to add_paths to add lines to the plot.

coastline

(optional) A SpatialPointsDataFrame-class object which defines the coastline (if applicable). This option is probably only suitable if aspectmode = "data" (see below).

coastline_paths

A named list of arguments that is passed to add_paths to add the coastline as lines to the plot.

plane

(optional) A number which defines the height of a horizontal, 2 dimensional plane that can be added to the plot to aid inference. Note that if stretch is provided (see below), the height of the plane is also adjusted by stretch internally.

plane_surface

(optional) A named list of arguments that is passed to add_surface to customise the plane added to the plot.

xlim

(optional) A numeric vector of length 2 which defines x axis limits. If not provided, these are calculated internally.

ylim

(optional) A numeric vector of length 2 which defines y axis limits. If not provided, these are calculated internally.

zlim

(optional) A numeric vector of length 2 which defines z axis limits. If not provided, these are calculated internally.

add_tick_text

A logical input that defines whether or not to add tick mark labels.

font

A named list of arguments that control plot font (see layout).

xtitle

(optional) A character string which defines the label for the x axis.

ytitle

(optional) A character string which defines the label for the y axis.

ztitle

(optional) A character string which defines the label for the z axis.

stretch

(optional) A number which is used to vertically stretch the height of a landscape. This can be useful if aspectmode = "data" but the magnitude of change horizontally versus vertically is very different. If supplied, stretch also affects the z values of the markers and paths (if add_markers and/or add_paths is/are specified).

aspectmode

A character which defines the shape of the plot: "cube" produces a cube; "data" provides a plot whether the size of the x, y and z axes is scaled according to the data.

eye

(optional) A named list of arguments that control the camera perspective (see layout).

verbose

A logical input which defines whether or not to display messages regarding function progress. This can be useful if aggregate or buffer are provided: for large rasters and/or many points, these steps may be slow.

...

Additional arguments passed to plot_ly.

Value

The function returns a plotly plot.

Details

The raster dimension should be less than approximately 1800 cells by 1800 cells. The coordinate system for the raster and, if applicable, markers and the buffer width, all need to be identical, whether this is implicit or specified explicitly.

Author

Edward Lavender

Examples

#### Define some bathymetry data library(raster)
#> Loading required package: sp
r <- dat_gebco r[r[] > 0] <- 0 #### Example 1: Plot a landscape using default options pretty_scape_3d(r = r)
#> Defining plot properties... #> Producing plot...
#### Example 2: Adjusting axes via zlim, ylim, zlim and font arguments pretty_scape_3d(r = r, xlim = c(-5.5, -5.3), font = list("Times"))
#> Defining plot properties... #> Producing plot...
#### Example 3: Change the aspectmode to "data": # The x, y and z values should be in the same units. # Here, depth is in m, so we'll project the raster to UTM coordinates: r <- raster::projectRaster(r, crs = sp::CRS("+proj=utm +zone=29 ellps=WGS84"))
#> Warning: Discarded datum Unknown based on WGS84 ellipsoid in CRS definition
pretty_scape_3d(r = r, aspectmode = "data")
#> Defining plot properties... #> Producing plot...
# For large areas, it can be helpful to vertically stretch the raster pretty_scape_3d(r = r, stretch = 50, aspectmode = "data")
#> Defining plot properties... #> Producing plot...
#### Example 4: Aggregrate the raster via aggregate # This is necessary for large rasters for plotly to produce the plot. pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", aggregate = list(fact = 2, fun = mean))
#> Aggregating raster... #> Defining plot properties... #> Producing plot...
#### Example 5: Add points via add_markers and zoom into landscape around points # Add points xyz <- matrix(raster::coordinates(r)[500:520, ], ncol = 2) xyz <- data.frame(x = xyz[, 1], y = xyz[, 2], z = -500) pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", add_markers = list(x = xyz$x, xyz$y, xyz$z))
#> Defining plot properties... #> Producing plot...
#> Warning: add_markers must be a named list with x, y and z coordinates; add_markers input ignored.
# Control point characteristics pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", add_markers = list(x = xyz$x, y = xyz$y, z = xyz$z, marker = list(color = "red")))
#> Defining plot properties... #> Producing plot...
#> Warning: `arrange_()` was deprecated in dplyr 0.7.0. #> Please use `arrange()` instead. #> See vignette('programming') for more help
# Zoom into landscape around points via buffer argument # Note that the units are in m here (since we're using the UTM coordinate system) pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", add_markers = list(x = xyz$x, y = xyz$y, z = xyz$z, marker = list(color = "red")), buffer = list(width = 1500))
#> Cropping spatial data around buffered points...
#> Warning: Discarded datum Unknown based on WGS84 ellipsoid in CRS definition
#> Defining plot properties... #> Producing plot...
#### Example 6: Add lines via add lines # Note that the legend for these lines is hidden automatically pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", add_paths = list(x = xyz$x, y = xyz$y, z = xyz$z))
#> Defining plot properties... #> Producing plot...
#### Example 6: Incorporate coastline via add_coastline and coastline_paths # r and coastline need to have same crs coastline <- sp::spTransform(dat_coast_around_oban, raster::crs(r))
#> Warning: NULL source CRS comment, falling back to PROJ string
pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", coastline = coastline)
#> Defining plot properties... #> Producing plot...
# Control coastline graphical parameters # Note that the legend is hidden automatically pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", coastline = coastline, coastline_paths = list(line = list(color = "red")))
#> Defining plot properties... #> Producing plot...
#### Example 7: Add plane # Note that the plane height is automatically adjusted by stretch pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", plane = -50)
#> Defining plot properties... #> Producing plot...
# Customise via plane_surface # Note that the legend is hidden automatically pretty_scape_3d(r = r, stretch = 50, aspectmode = "data", plane = -50, plane_surface = list(colorscale = "blue", showscale = FALSE))
#> Defining plot properties... #> Producing plot...