Nothing
#' Maps of predicted abundance from Boosted Regression Tree modelling
#'
#' Generates maps from the outputs of gbm.step then Gbm.predict.grids, handled automatically within
#' gbm.auto but can be run alone, and generates representativeness surfaces from the output of
#' gbm.rsb.
#'
#' @author Simon Dedman, \email{simondedman@@gmail.com}
#' @import ggplot2
#' @importFrom ggmap get_map ggmap register_google
#' @importFrom ggspatial layer_spatial
#' @importFrom lubridate today
#' @importFrom stars geom_stars st_as_stars
#' @importFrom stats setNames
#' @importFrom sf st_set_crs st_bbox st_transform st_as_sfc st_as_sf st_buffer
#' @importFrom starsExtra trim2
#' @importFrom viridis scale_fill_viridis
#' @export
#'
#' @param predabund Predicted abundance data frame produced by gbm.auto (Abundance_Preds_only.csv),
#' with Latitude, Longitude, and Predicted Abundance columns. Default NULL. You need to read the csv
#' in R if not already present as an object in the environment.
#' @param predabundlon Longitude column number. Default 2.
#' @param predabundlat Latitude column number. Default 1.
#' @param predabundpreds Predicted abundance column number, default 3.
#' @param myLocation Location for extents, format c(xmin, ymin, xmax, ymax). Default NULL, extents
#' autocreated from data.
#' @param trim Remove NA & <=0 values and crop to remaining date extents? Default TRUE.
#' @param trimfivepct Replace anything < 5% of the max value (i.e. < 95% UD contour in home range
#' analysis) with NA since it won't be drawn (for movegroup dBBMMs). Default FALSE.
#' @param scale100 Scale Predicted Abundance to 100? Default FALSE.
#' @param gmapsAPI Enter your Google maps API here, quoted character string. Default NULL.
#' @param mapsource Source for ggmap::get_map; uses Stamen as fallback if no Google Maps API present
#' . Options: "google", "stamen", "gbm.basemap". Default "google". Using "gbm.basemap" requires one
#' to have run that functiuon already, and enter its location using the shape paramater below.
#' @param googlemap If pulling basemap from Google maps, this sets expansion factors since Google
#' Maps tiling zoom setup doesn't align to myLocation extents. Default TRUE.
#' @param maptype Type of map for ggmap::get_map param maptype. Options: Google mapsource: "terrain",
#' "terrain-background", "satellite", "roadmap", "hybrid". Stamen mapsource: "terrain",
#' "terrain-background", "terrain-labels", "terrain-lines", "watercolor", "toner", "toner-2010",
#' "toner-2011", "toner-background", "toner-hybrid", "toner-labels", "toner-lines", "toner-lite".
#' @param darkenproportion Amount to darken the google/stamen basemap, 0-1. Default 0.
#' @param mapzoom Highest number = zoomed in. Google: 3 (continent) - 21 (building). stamen: 0-18.
#' Default 9.
#' @param shape If mapsource is "gbm.basemap", enter the full path to gbm.basemaps downloaded map,
#' typically Crop_Map.shp, including the .shp. Default NULL. Can also name an existing object in the
#' environment, read in with sf::st_read.
#' @param expandfactor Extents expansion factor for basemap. default 0.
#' @param colourscale Scale fill colour scheme to use, default "viridis", other option is
#' "gradient".
#' @param colorscale Scale fill colour scheme to use, default NULL, populating this will overwrite
#' colourscale.
#' @param heatcolours Vector of colours if gradient selected for colourscale, defaults to heatmap
#' theme.
#' @param colournumber Number of colours to spread heatcolours over, if gradient selected for
#' colourscale. Default 8.
#' @param colourscalelimits Colour scale limits, default NULL, vector of 2, e.g. c(0, 0).
#' @param colourscalebreaks Colour scale breaks, default NULL.
#' @param colourscalelabels Colour scale labels, default NULL, must match number of breaks.
#' @param colourscaleexpand Colour scale expand, default NULL, vector of 2, e.g. c(0, 0).
#' @param studyspecies Name of your study species, appears in plot title and savename. Default
#' "MySpecies".
#' @param plottitle Title of the resultant plot, default paste0("Predicted abundance of ",
#' studyspecies).
#' @param plotsubtitle Plot subtitle, default ""CPUE". Can add the n of your individuals.
#' @param legendtitle Legend title, default "CPUE".
#' @param plotcaption Plot caption, default "gbm.auto::gbm.mapsf" + today's date.
#' @param axisxlabel Default "Longitude".
#' @param axisylabel Default "Latitude".
#' @param legendposition Vector of 2, format c(1,2), Proportional distance of (middle?) of legend
#' box from L to R, percent distance from Bottom to Top. Values 0 to 1. Default c(0.05, 0.15).
#' @param fontsize Font size, default 12.
#' @param fontfamily = Font family, default "Times New Roman".
#' @param filesavename File savename, default today's date + studyspecies + legendtitle.
#' @param savedir Save outputs to a temporary directory (default) else change to current directory
#' e.g. "/home/me/folder". Do not use getwd() here. No terminal slash. E.g.
#' paste0(movegroupsavedir, "Plot/") .
#' @param receiverlats Vector of latitudes for receivers to be plotted.
#' @param receiverlons Vector of longitudes for receivers to be plotted. Same length as receiverlats.
#' @param receivernames Vector of names for receivers to be plotted. Same length as receiverlats.
#' @param receiverrange Single (will be recycled), or vector (same length as receiverlats) of
#' detection ranges in metres for receivers to be plotted. If you have a max and a (e.g.) 90 percent
#' detection range, probably use max.
#' @param recpointscol Colour of receiver centrepoint outlines. Default "black".
#' @param recpointsfill Colour of receiver centrepoint fills. Default "white".
#' @param recpointsalpha Alpha value of receiver centrepoint fills, 0 (invisible) to 1 (fully
#' visible). Default 0.5.
#' @param recpointssize Size of receiver points. Default 1.
#' @param recpointsshape Shape of receiver points, default 21, circle with outline and fill.
#' @param recbufcol Colour of the receiver buffer circle outlines. Default "grey75"
#' @param recbuffill Colour of the receiver buffer circle fills. Default "grey".
#' @param recbufalpha Alpha value of receiver buffer fills, 0 (invisible) to 1 (fully visible).
#' Default 0.5.
#' @param reclabcol Receiver label text colour. Default "black".
#' @param reclabfill Receiver label fill colour, NA for no fill. Default NA.
#' @param reclabnudgex Receiver label offset nudge in X dimension. Default 0.
#' @param reclabnudgey Receiver label offset nudge in Y dimension. Default -200.
#' @param reclabpad Receiver label padding in lines. Default 0.
#' @param reclabrad Receiver label radius in lines. Default 0.15.
#' @param reclabbord Receiver label border in mm. Default 0.
#'
#' @return Species abundance maps using data provided by gbm.auto, and
#' Representativeness Surface Builder maps using data provided by gbm.rsb, to be
#' run in a png/par/gbm.map/dev.off sequence.
#'
#' @details
#'
#' Error in seq.default(xlim\[1\], xlim\[2\], by = byx):wrong sign in 'by' argument
#' Check that your lat & long columns are the right way around. Ensure grids (predabund) data are
#' gridded, i.e. they are in a regular pattern of same/similar lines of lat/lon, even if they're
#' missing sections.
#'
#' Suggested parameter values:
#' z = rsbdf\[,"Unrepresentativeness"\]
#'
#' mapmain = "Unrepresentativeness: "
#'
#' legendtitle = "UnRep 0-1"
#'
#' ## How to get Google map basemaps
#' (from https://www.youtube.com/watch?v=O5cUoVpVUjU):
#'
#' 1. Sign up with dev console: a. You must enter credit card details, but won’t be charged if your
#' daily API requests stay under the limit. b. Follow the link:
#' https://console.cloud.google.com/projectselector2/apis/dashboard?supportedpurview=project c.
#' Sign up for Google cloud account (it may auto populate your current gmail), click agree and
#' continue. d. Click the navigation email in the top left corner and click on Billing. e. Create a
#' billing account – they will NOT auto charge after trial ends. f. Enter information, click on
#' 'start my free trial'. They may offer a free credit for trying out their service. More pricing
#' details: https://mapsplatform.google.com/pricing/ . g. Click “Select a Project” then
#' “New project” in the top right corner. h. Enter Project Name, leave Location as is, click
#' “Create”. i. You should now see your project name at the top, where the drop-down menu is.
#'
#' 2. Enable Maps and Places API: a. Click 'Library' on the left. b. In the search field type “Maps”
#' . c. Scroll down, click “Maps Java Script API”. d. Click Enable. e. Click 'Library' again, search
#' “Places”, click on “Places API”. f. Click Enable.
#'
#' 3. Create Credentials for API Key: a. Return to 'APIs & Services' page. b. Click on Credentials.
#' c. At the top click 'Create Credentials > API Key'. d. API key should pop up with option to copy
#' it. e. You can restrict the key if you want by following steps 4 & 5 here:
#' https://www.youtube.com/watch?v=O5cUoVpVUjU&t=232s
#'
#' @examples
#' \donttest{
#' # Not run
#' }
gbm.mapsf <- function(
predabund = NULL, # predicted abundance data frame produced by gbm.auto (Abundance_Preds_only.csv), with Latitude, Longitude, and Predicted Abundance columns.
predabundlon = 2, # Longitude column number.
predabundlat = 1, # Latitude column number.
predabundpreds = 3, # Predicted abundance column number.
myLocation = NULL, # location for extents, format c(xmin, ymin, xmax, ymax).
# Default NULL, extents autocreated from data.
# c(-79.3, 25.68331, -79.24, 25.78)
trim = TRUE, # remove NA & 0 values and crop to remaining date extents? Default TRUE.
trimfivepct = FALSE, # replace anything < 5% of the max value (i.e. < 95% UD contour in home range analysis) with NA since it won't be drawn (for movegroup dBBMMs).
scale100 = FALSE, # scale Predicted Abundance to 100? Default FALSE.
gmapsAPI = NULL, # enter your Google maps API here, quoted character string
mapsource = "google", # Source for ggmap::get_map; uses Stamen as fallback if no Google Maps API present. Options: "google", "stamen", "gbm.basemap".
googlemap = TRUE, # If pulling basemap from Google maps, this sets expansion factors since
# Google Maps tiling zoom setup doesn't align to myLocation extents.
maptype = "satellite", # Type of map for ggmap::get_map. Options: "terrain", "terrain-background", "satellite", "roadmap", "hybrid", "toner",
# "terrain-labels", "terrain-lines", "toner-2010", "toner-2011",
# "toner-background", "toner-hybrid", "toner-labels", "toner-lines", "toner-lite". Google options: “terrain”, “satellite”, “roadmap”, “hybrid”.
darkenproportion = 0, # amount to darken the basemap, 0-1.
mapzoom = NULL, # google: 3 (continent) - 21 (building). stamen: 0-18
shape = NULL, # If mapsource is "gbm.basemap", enter the full path to gbm.basemaps downloaded map, typically Crop_Map.shp, including the .shp.
expandfactor = 0, # extents expansion factor for basemap. default was 1.6
colourscale = "viridis", # Scale fill colour scheme to use, default "viridis", other option is "gradient".
colorscale = NULL, # Scale fill colour scheme to use, default NULL, populating this will overwrite colourscale.
heatcolours = c("white", "yellow", "orange","red", "brown4"), # Vector of colours if gradient selected for colourscale, defaults to heatmap theme.
colournumber = 8, # Number of colours to spread heatcolours over, if gradient selected for colourscale. Default 8.
colourscalelimits = NULL, # Colour scale limits, default NULL, vector of 2, e.g. c(0, 0).
colourscalebreaks = NULL, # Colour scale breaks, default NULL.
colourscalelabels = NULL, # Colour scale labels, default NULL, must match number of breaks.
colourscaleexpand = NULL, # Colour scale expand, default NULL, vector of 2, e.g. c(0, 0).
studyspecies = "MySpecies", # The name of your study species, appears in plot title and savename.
plottitle = paste0("Predicted abundance of ", studyspecies),
plotsubtitle = "CPUE", # Plot subtitle. Can add the n of your individuals.
legendtitle = "CPUE",
plotcaption = paste0("gbm.auto::gbm.mapsf, ", lubridate::today()),
axisxlabel = "Longitude",
axisylabel = "Latitude",
legendposition = c(0.05, 0.15), # Percent distance (of middle? of legend box) from L to R, percent distance from Bottom to Top.
fontsize = 12,
fontfamily = "Times New Roman",
filesavename = paste0(lubridate::today(), "_", studyspecies, "_", legendtitle, ".png"),
savedir = tempdir(), # file.path(work.dir, out.dir, "Scaled")
receiverlats = NULL, # vector of latitudes for receivers to be plotted
receiverlons = NULL, # vector of longitudes for receivers to be plotted
receivernames = NULL, # vector of names for receivers to be plotted
receiverrange = NULL, # single (will be recycled), or vector of detection ranges in metres for receivers to be plotted
recpointscol = "black", # Colour of receiver centrepoint outlines.
recpointsfill = "white", # Colour of receiver centrepoint fills.
recpointsalpha = 0.5, # Alpha value of receiver centrepoint fills, 0 (invisible) to 1 (fully visible).
recpointssize = 1, # Size of receiver points.
recpointsshape = 21, # Shape of receiver points, default 21, circle with outline and fill.
recbufcol = "grey75", # Colour of the receiver buffer circle outlines.
recbuffill = "grey", # Colour of the receiver buffer circle fills.
recbufalpha = 0.5, # Alpha value of receiver buffer fills, 0 (invisible) to 1 (fully visible).
reclabcol = "black", # Receiver label text colour.
reclabfill = NA, # Receiver label fill colour, NA for no fill.
reclabnudgex = 0, # Receiver label offset nudge in X dimension.
reclabnudgey = -200, # Receiver label offset nudge in Y dimension.
reclabpad = 0, # Receiver label padding in lines.
reclabrad = 0.15, # Receiver label radius in lines.
reclabbord = 0 # Receiver label border in mm.
){
# Todo:
# unrep exponential breaks for RSB legend: breaks = exp01seq
# gbm.auto L1847
# linear01seq <- seq(from = 0, to = 1, length.out = 9) #linear sequence from 0:1, 9 bins
# exp01seq <- expm1(4*linear01seq)/expm1(4) # exponentiate to change shape then scale back to 1
# gbm.auto allow entry for user preference elements, google, etc.
# remove Hans as gbm.auto author since the stuff he contributed to is gone?
# check receiver inputs are the correct lengths, if present.
if (!is.null(receiverlats) & !is.null(receiverlons)) if (length(receiverlats) != length(receiverlons)) stop("length of receiverlats must equal length of receiverlons")
if (!is.null(receiverlats) & !is.null(receivernames)) if (length(receiverlats) != length(receivernames)) stop("length of receivernames must equal length of receiverlats/lons")
if (!is.null(receiverlats) & !is.null(receiverrange)) if (length(receiverrange) != length(receiverlons)) if (length(receiverrange) != 1) stop("length of receiverrange must equal length of receiverlats/lons, or 1")
# Create receiver objects
if (!is.null(receiverlats) & !is.null(receiverlons)) {
receiver <- data.frame(lon = receiverlons,
lat = receiverlats)
receiver <- sf::st_as_sf(receiver, coords = c("lon","lat")) |>
sf::st_set_crs(4326) |>
sf::st_transform(3857)
if (!is.null(receivernames)) {
receiver <- cbind(receiver, receivernames)
}
if (!is.null(receiverrange)) {
receiver <- cbind(receiver, receiverrange)
}
}
# location for extents, format c(xmin, ymin, xmax, ymax). Default NULL, extents autocreated from data.
if (is.null(myLocation)) {
myLocation <- c(min(predabund[,predabundlon], na.rm = TRUE),
min(predabund[,predabundlat], na.rm = TRUE),
max(predabund[,predabundlon], na.rm = TRUE),
max(predabund[,predabundlat], na.rm = TRUE))
}
if (!is.null(gmapsAPI)) ggmap::register_google(key = gmapsAPI, # an api key
account_type = "standard",
write = TRUE)
if (mapsource != "google") googlemap <- FALSE else googlemap <- TRUE # in case user forgot to set both the same
if (expandfactor != 0) { # grow bounds extents if requested
xmid <- mean(myLocation[c(1,3)])
ymid <- mean(myLocation[c(2,4)])
xmax <- ((myLocation[3] - xmid) * expandfactor) + xmid #updated for sf/st
xmin <- xmid - ((xmid - myLocation[1]) * expandfactor)
ymax <- ((myLocation[4] - ymid) * expandfactor) + ymid
ymin <- ymid - ((ymid - myLocation[2]) * expandfactor)
myLocation <- c(xmin, ymin, xmax, ymax)
}
if (mapsource == "google" & is.null(mapzoom)) {
# Created lookup table for degrees to mapzoom by eye at all zoom levels
lonvec <- c(0.00042724609375,
0.0008544921875,
0.001708984375,
0.00341796875,
0.0068359375,
0.013671875,
0.02734375,
0.0546875,
0.109375,
0.21875,
0.4375,
0.875,
1.75,
3.5,
7,
13.5,
27,
55,
105,
145)
# lookup lat & lon against lookup table to get independent zoom levels
mapzoomlon <- 22 - (
findInterval(x = max(predabund[,predabundlon], na.rm = TRUE) - min(predabund[,predabundlon], na.rm = TRUE),
vec = lonvec,
left.open = TRUE
) + 1)
latvec <- c(0.0003662109375,
0.000732421875,
0.00146484375,
0.0029296875,
0.005859375,
0.01171875,
0.0234375,
0.046875,
0.09375,
0.1875,
0.375,
0.75,
1.5,
3,
6,
12,
25,
47,
87,
145)
mapzoomlat <- 22 - (
findInterval(x = max(predabund[,predabundlat], na.rm = TRUE) - min(predabund[,predabundlat], na.rm = TRUE),
vec = latvec,
left.open = TRUE
) + 1)
# Do MIN zoom i.e. least zoomed in since otherwise it will cut off one dimension's data
mapzoom <- min(mapzoomlon, mapzoomlat)
}
if (googlemap) myLocation <- c(mean(c(myLocation[1], myLocation[3])), mean(c(myLocation[2], myLocation[4]))) # googlemap needs a center lon lat
# mapsource
if (mapsource == "gbm.basemap") {
# if user provided location of .shp file, read in. If shape is already read with st_read, leave alone.
if (is.character(shape)) shape = st_read(dsn = shape)
# autoheight <- (6 / (attr(myMap, "bb")[[4]] - attr(myMap, "bb")[[2]])) * (attr(myMap, "bb")[[3]] - attr(myMap, "bb")[[1]]) * 1.2
# if (googlemap) autoheight <- 6.4 # googlemap pulls tiles for a centre point hence will always be square. But needs a bit extra for title area.
autoheight <- 6.4 # dummy
#autoheight to build####
} else { # mapsource ifelse
myMap <- ggmap::get_map(
location = myLocation, # -62.57564 28.64368 33.78889 63.68533 # stamen etc want a bounding box
zoom = mapzoom, # 3 (continent) - 21 (building). Stamen: 0-18
# scale = "auto", # default "auto", 1, 2, 4 all the same
messaging = TRUE, #
source = mapsource, # "google" # using stamen as fallback
maptype = maptype, # "satellite"
crop = TRUE # google maps crs = 4326
)
# Define a function to fix the bbox to be in EPSG:3857
# https://stackoverflow.com/a/50844502/1736291 Fixes "error no lon value" in ggmap below
ggmap_bbox <- function(map) {
if (!inherits(map, "ggmap")) stop("map must be a ggmap object")
# Extract the bounding box (in lat/lon) from the ggmap to a numeric vector,
# and set the names to what sf::st_bbox expects:
map_bbox <- stats::setNames(unlist(attr(map, "bb")), c("ymin", "xmin", "ymax", "xmax"))
# Convert the bbox to an sf polygon, transform it to 3857,
# and convert back to a bbox (convoluted, but it works)
bbox_3857 <- sf::st_bbox(sf::st_transform(sf::st_as_sfc(sf::st_bbox(map_bbox, crs = 4326)), 3857))
# Overwrite the bbox of the ggmap object with the transformed coordinates
attr(map, "bb")$ll.lat <- bbox_3857["ymin"]
attr(map, "bb")$ll.lon <- bbox_3857["xmin"]
attr(map, "bb")$ur.lat <- bbox_3857["ymax"]
attr(map, "bb")$ur.lon <- bbox_3857["xmax"]
map
}
myMap <- ggmap_bbox(myMap) # Use the function. Resulting map is CRS 3857
# Automate width * height adjustments for different map extent / ratio
# 6 (manually chosen width, below), divided by width range times by height range
# Maintains ratio by scales height to width(6). Then *1.2 because it still wasn't perfect.
# attr(myMap, "bb")[[4]] - attr(myMap, "bb")[[2]] # longitude, x, width, bind as 6
# attr(myMap, "bb")[[3]] - attr(myMap, "bb")[[1]] # latitude, y, height
autoheight <- (6 / (attr(myMap, "bb")[[4]] - attr(myMap, "bb")[[2]])) * (attr(myMap, "bb")[[3]] - attr(myMap, "bb")[[1]]) * 1.2
if (googlemap) autoheight <- 6.4 # googlemap pulls tiles for a centre point hence will always be square. But needs a bit extra for title area.
} # close mapsource ifelse
# remove extra columns from predabund so they don't become additional layers in stars raster
predabund <- data.frame(Latitude = predabund[, predabundlat],
Longitude = predabund[, predabundlon],
PredAbund = predabund[, predabundpreds])
# create stars from predabund
predabundstars <- stars::st_as_stars(predabund, coords = c(predabundlon, predabundlat)) |>
sf::st_set_crs(4326) # one of (i) character: a string accepted by GDAL, (ii) integer, a valid EPSG value (numeric), or (iii) an object of class crs.
if (trim) { # trim raster extent to data?
is.na(predabundstars[[1]]) <- predabundstars[[1]] == 0 # replace char pattern (0) in whole df/tbl with NA
if (trimfivepct) is.na(predabundstars[[1]]) <- predabundstars[[1]] < (max(predabundstars[[1]], na.rm = TRUE) * 0.05) # replace anything < 95% contour with NA since it won't be drawn
}
predabundstars <- starsExtra::trim2(predabundstars) # remove NA columns, which were all zero columns. This changes the bbox accordingly
if (scale100) predabundstars[[1]] <- (predabundstars[[1]] / max(predabundstars[[1]], na.rm = TRUE)) * 100 # convert from raw values to 0:100 scale so legend is 0:100%
# set colourscale from colorscale
if (!is.null(colorscale)) colourscale <- colorscale
# ggplot() + #plot lines by year
# ggspatial::layer_spatial(shape, col = "black") +
# stars::geom_stars(data = predabundstars |> sf::st_transform(3857), inherit.aes = FALSE)
# # don't need to see the rest, geom_stars & afters work outside of {ifelse}, not within: stops after later_spatial
# # if order flipped (ggmap then layerspatial: layerspatial works)
# replace colourscale params with ggplot2 defaults if left NULL
if (is.null(colourscalebreaks)) colourscalebreaks <- ggplot2::waiver()
if (is.null(colourscalelabels)) colourscalelabels <- ggplot2::waiver()
if (is.null(colourscaleexpand)) colourscaleexpand <- ggplot2::waiver() # c(0, 0),
# plot map
if (mapsource == "gbm.basemap") {
p <- ggplot() + #plot lines by year
ggspatial::layer_spatial(shape, col = "black")
} else {
p <- ggmap::ggmap(myMap, # basemap CRS = 3857? Doesn't plot on its own, don't worry
darken = c(darkenproportion, "black"))
} # close mapsource ifelse
p <- p +
# Prediction surface
# need to convert points to raster using byx code from gbm.map
stars::geom_stars(data = predabundstars |> sf::st_transform(3857), inherit.aes = FALSE) +
# # receiver centrepoints
{if (!is.null(receiverlats) & !is.null(receiverlons))
ggplot2::geom_sf(data = receiver |>
sf::st_transform(3857), # Vector transform after st_contour
# already 3857 above so converting twice but it ain't broke
colour = recpointscol,
fill = recpointsfill,
alpha = recpointsalpha,
size = recpointssize,
shape = recpointsshape,
inherit.aes = FALSE,
)
} +
# receiver buffer circles
{if (!is.null(receiverlats) & !is.null(receiverlons) & !is.null(receiverrange))
ggplot2::geom_sf(data = sf::st_buffer(receiver, dist = receiverrange) |>
sf::st_transform(3857), # Vector transform after st_contour
# already 3857 above so converting twice but it ain't broke
colour = recbufcol,
fill = recbuffill,
alpha = recbufalpha,
inherit.aes = FALSE
)
} +
# receiver labels
{if (!is.null(receiverlats) & !is.null(receiverlons) & !is.null(receivernames))
ggplot2::geom_sf_label(data = receiver |>
sf::st_transform(3857), # Vector transform after st_contour
# already 3857 above so converting twice but it ain't broke
colour = reclabcol,
fill = reclabfill,
inherit.aes = FALSE,
nudge_x = reclabnudgex,
nudge_y = reclabnudgey,
label.padding = unit(reclabpad, "lines"), # 0.25
label.r = unit(reclabrad, "lines"),
label.size = reclabbord, # 0.25
ggplot2::aes(label = receivernames)
)
} +
# CPUE scale colours
{if (colourscale == "viridis")
viridis::scale_fill_viridis(
limits = colourscalelimits, # c(0, 1),
breaks = colourscalebreaks,
labels = colourscalelabels,
expand = colourscaleexpand, # c(0, 0),
alpha = 1, # 0:1
begin = 0, # hue
end = 1, # hue
direction = 1, # colour order, 1 or -1
discrete = FALSE, # false = continuous
option = "D", # A magma B inferno C plasma D viridis E cividis F rocket G mako H turbo
space = "Lab",
na.value = "grey50",
guide = "colourbar",
aesthetics = "fill",
name = legendtitle,
position = "right"
)
} +
# CPUE scale colours
{if (colourscale == "gradient")
scale_fill_gradientn(
limits = colourscalelimits, # c(0, 1),
breaks = colourscalebreaks,
labels = colourscalelabels,
expand = colourscaleexpand, # c(0, 0),
name = legendtitle,
position = "right",
colours = colorRampPalette(heatcolours)(colournumber), # Vector of colours to use for n-colour gradient.
na.value = "grey50"
)
} +
ggplot2::ggtitle(plottitle, subtitle = plotsubtitle) +
ggplot2::labs(x = axisxlabel, y = axisylabel, caption = plotcaption) +
ggplot2::theme_minimal() +
ggplot2::theme(
legend.position = legendposition, #%dist (of middle? of legend box) from L to R, %dist from Bot to Top
legend.spacing.x = ggplot2::unit(0, 'cm'), #compress spacing between legend items, this is min
legend.spacing.y = ggplot2::unit(0, 'cm'), #compress spacing between legend items, this is min
legend.title = ggplot2::element_text(size = 8),
legend.text = ggplot2::element_text(size = 8),
legend.background = ggplot2::element_rect(fill = "white", colour = NA), # element_blank(),
panel.background = ggplot2::element_rect(fill = "white", colour = "grey50"), # white background
plot.background = ggplot2::element_rect(fill = "white", colour = "grey50"), # white background
legend.key = ggplot2::element_blank(),
text = ggplot2::element_text(size = fontsize, family = fontfamily)
) # removed whitespace buffer around legend boxes which is nice
ggplot2::ggsave(filename = filesavename,
plot = p, # ggplot2::last_plot()
device = "png",
path = savedir,
scale = 1,
#changes how big lines & legend items & axes & titles are relative to basemap. Smaller number = bigger items
width = 6, height = autoheight, units = "in", dpi = 600, limitsize = TRUE)
} # close function
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.