Tripneustes ventricosus
Tripneustes ventricosus have a broad distribution, from south Florida and Bermuda up to the south of Brazil, inhabiting various habitats. It can exert significant grazing pressure on coral reefs, although it usually has a more significant impact on seagrass beds.
White sea urchin. Cifonauta image database. Available at: http://cifonauta.cebimar.usp.br/media/9531/ Accessed: 2024-08-12. CC BY-NC-SA 3.0 DEED
Current and future distribution (SDMs)
Both E. lucunter and T. ventricosus showed areas of higher suitability in the Caribbean and south of the Gulf of Mexico, especially along the coast of Campeche to Quintana Roo (Mexico). Both species also show areas of high suitability along the Antilles. Tripneustes ventricosus seems to be less tolerant to colder temperatures.
Code
suppressPackageStartupMessages(library(terra))
suppressPackageStartupMessages(library(sf))
library(leaflet)
library(leaflet.providers)
library(leafem)
<- "trve"
sp
<- paste0("../results/", sp, "/predictions/")
basedir
<- list.files(basedir)
sdm_proj <- sdm_proj[grepl("mean", sdm_proj)]
sdm_proj <- sdm_proj[grepl("cont", sdm_proj)]
sdm_proj_cont
<- rast(paste0(basedir, sdm_proj_cont))
proj_lays <- project(proj_lays, "EPSG:3857")
proj_lays
# Normalize to 0-1
<- (proj_lays - min(terra::minmax(proj_lays$trve_mean_m6_cont_current)[1,])) / (terra::minmax(proj_lays$trve_mean_m6_cont_current)[2,] - terra::minmax(proj_lays$trve_mean_m6_cont_current)[1,])
proj_lays
# Get areas of extrapolation
<- proj_lays[[2:4]]
extrap_lays <= terra::minmax(proj_lays$trve_mean_m6_cont_current)[2,]] <- NA
extrap_lays[extrap_lays !is.na(extrap_lays)] <- 1
extrap_lays[
<- lapply(1:3, function(id){
extrap_shape ::project(terra::as.polygons(extrap_lays[[id]]), "EPSG:4326")
terra
})
# Set maximum to the maximum of current layer
> 1] <- 1
proj_lays[proj_lays
# Load points
<- read.csv(paste0("../data/", sp, "/", sp, "_filt.csv"))
pts <- vect(pts, geom = c("x", "y"), crs = crs(rast(paste0(basedir, sdm_proj_cont[1]))))
pts <- project(pts, "EPSG:4326")
pts <- as.data.frame(geom(pts))
pts
# Plot maps
leaflet() %>%
#addProviderTiles("OpenStreetMap.Mapnik", group = "OSM") %>%
addProviderTiles("Esri.WorldGrayCanvas", group = "ESRI Gray") %>%
addRasterImage(
1]],
proj_lays[[project = F,
colors = colorNumeric(
palette = rev(c("#A84C00", "#D97D27", "#F5BD44", "#FFD561", "#FFF291",
"#FFFFBF", "#E0F3F8", "#ABD9E9", "#74ADD1", "#4575B4", "#313695")),
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "Current"
%>%
) addRasterImage(
2]],
proj_lays[[project = F,
colors = colorNumeric(
palette = rev(c("#A84C00", "#D97D27", "#F5BD44", "#FFD561", "#FFF291",
"#FFFFBF", "#E0F3F8", "#ABD9E9", "#74ADD1", "#4575B4", "#313695")),
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP1 (RCP2.6)"
%>%
) addPolygons(data = extrap_shape[[1]], group = "SSP1 (RCP2.6)") %>%
addRasterImage(
3]],
proj_lays[[project = F,
colors = colorNumeric(
palette = rev(c("#A84C00", "#D97D27", "#F5BD44", "#FFD561", "#FFF291",
"#FFFFBF", "#E0F3F8", "#ABD9E9", "#74ADD1", "#4575B4", "#313695")),
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP2 (RCP4.5)"
%>%
) addPolygons(data = extrap_shape[[2]], group = "SSP2 (RCP4.5)") %>%
addRasterImage(
4]],
proj_lays[[project = F,
colors = colorNumeric(
palette = rev(c("#A84C00", "#D97D27", "#F5BD44", "#FFD561", "#FFF291",
"#FFFFBF", "#E0F3F8", "#ABD9E9", "#74ADD1", "#4575B4", "#313695")),
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP3 (RCP7.0)"
%>%
) addPolygons(data = extrap_shape[[3]], group = "SSP3 (RCP7.0)") %>%
addLegend(pal = colorNumeric(
palette = c("#A84C00", "#D97D27", "#F5BD44", "#FFD561", "#FFF291",
"#FFFFBF", "#E0F3F8", "#ABD9E9", "#74ADD1", "#4575B4", "#313695"),
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
values = values(proj_lays[[1]]), title = "ROR", opacity = 1, position = "bottomright",
), labFormat = labelFormat(transform = function(x) sort(x, decreasing = TRUE))) %>%
addCircleMarkers(lng = pts$x, lat = pts$y,
#clusterOptions = markerClusterOptions(),
radius = 5, weight = 2.5,
group = "Occurrence") %>%
addLayersControl(
baseGroups = c("Current", "SSP1 (RCP2.6)", "SSP2 (RCP4.5)", "SSP3 (RCP7.0)"),
overlayGroups = c("Occurrence"),
options = layersControlOptions(collapsed = FALSE)
%>%
) setView(-60, 0, zoom=3)
Changes in future distribution (SDMs)
Tripneustes ventricosus do not present any apparent loss in its distribution range compared to the current scenario. This species would increase its range of suitable areas to the north and to the south.
Code
<- proj_lays[[2:4]] - proj_lays[[1]]
delta
# Plot maps
leaflet() %>%
#addProviderTiles("OpenStreetMap.Mapnik", group = "OSM") %>%
addProviderTiles("Esri.WorldGrayCanvas", group = "ESRI Gray") %>%
addRasterImage(
1]],
delta[[project = F,
colors = colorNumeric(
palette = "BrBG",
domain = c(-1,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP1 (RCP2.6)"
%>%
) addRasterImage(
2]],
delta[[project = F,
colors = colorNumeric(
palette = "BrBG",
domain = c(-1,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP2 (RCP4.5)"
%>%
) addRasterImage(
3]],
delta[[project = F,
colors = colorNumeric(
palette = "BrBG",
domain = c(-1,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP3 (RCP7.0)"
%>%
) addLegend(pal = colorNumeric(
palette = "BrBG",
domain = c(-1,1),
na.color = "#00000000",
alpha = FALSE,
reverse = T
values = seq(-1, 1, by = 0.1), title = "Delta ROR", opacity = 1, position = "bottomright",
), labFormat = labelFormat(transform = function(x) sort(x, decreasing = TRUE))) %>%
addCircleMarkers(lng = pts$x, lat = pts$y,
#clusterOptions = markerClusterOptions(),
radius = 5, weight = 2.5,
group = "Occurrence") %>%
addLayersControl(
baseGroups = c("SSP1 (RCP2.6)", "SSP2 (RCP4.5)", "SSP3 (RCP7.0)"),
overlayGroups = c("Occurrence"),
options = layersControlOptions(collapsed = FALSE)
%>%
) setView(-60, 0, zoom=3)
Current and future distribution (mechanistic model)
Tripneustes ventricosus had a smaller suitable area than the other species. It was more concentrated in tropical areas mainly from Florida to the south of Rio de Janeiro. The loss of suitable areas in the future was proportionally similar to the other species (12, 47 and 65% in the SSP1, SSP2, and SSP3 scenarios respectively), but T. ventricosus suitable area was ~20% smaller than the one of L. variegatus and ~12% smaller than the suitable area of E. lucunter.
Code
# Load layers and prepare
# Load threshold data ----
load("../data/sst_limits/allspecies_oisst_thvalues.RData")
# Load results ----
<- "trve" # Each species is run separately [try "eclu" and "trve"]
sp
# Load rasters generated before
<- rast(paste0("../data/sst_limits/", sp, "_current_thresh.tif"))
curr <- rast(paste0("../data/sst_limits/", sp, "_", "ssp126", "_thresh.tif"))
ssp1 <- rast(paste0("../data/sst_limits/", sp, "_", "ssp245", "_thresh.tif"))
ssp2 <- rast(paste0("../data/sst_limits/", sp, "_", "ssp370", "_thresh.tif"))
ssp3
<- project(curr, "EPSG:3857")
curr <- project(ssp1, "EPSG:3857")
ssp1 <- project(ssp2, "EPSG:3857")
ssp2 <- project(ssp3, "EPSG:3857")
ssp3
# Get the percentage of time to use as threshold (mean of min and max point)
<- round(((thresholds[[sp]]$time_inrange_hottest_point +
lval $time_inrange_coolest_point)/2),
thresholds[[sp]]2) # round to 2 digits
# Get the polygons of the areas that are suitable
<- function(x){
get.pol # temp <- terra::app(x, function(x){
# x[x < lval] <- NA
# x[x >= lval] <- 1
# x
# })
# temp <- as.polygons(temp)
# temp <- aggregate(buffer(temp,0.0001)) # We use a negligible value here
# # to solve problems in the pols
# # conversion.
# temp <- project(temp, "EPSG:4326")
# # temp <- st_as_sf(temp)
# # temp <- st_set_crs(temp, crs("EPSG:4326"))
# temp
< lval] <- NA
x[x >= lval] <- 1
x[x ::project(terra::as.polygons(x), "EPSG:4326")
terra
}
<- get.pol(curr)
curr.p <- get.pol(ssp1)
ssp1.p <- get.pol(ssp2)
ssp2.p <- get.pol(ssp3)
ssp3.p
# Plot maps
leaflet() %>%
#addProviderTiles("OpenStreetMap.Mapnik", group = "OSM") %>%
addProviderTiles("Esri.WorldGrayCanvas", group = "ESRI Gray") %>%
addRasterImage(
curr,project = F,
colors = colorNumeric(
palette = "Spectral",
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "Current"
%>%
) addPolygons(data = curr.p,
group = "Current Suitable") %>%
addRasterImage(
ssp1,project = F,
colors = colorNumeric(
palette = "Spectral",
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP1 (RCP2.6)"
%>%
) addPolygons(data = ssp1.p,
group = "SSP1 Suitable") %>%
addRasterImage(
ssp2,project = F,
colors = colorNumeric(
palette = "Spectral",
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP2 (RCP4.5)"
%>%
) addPolygons(data = ssp2.p,
group = "SSP2 Suitable") %>%
addRasterImage(
ssp3,project = F,
colors = colorNumeric(
palette = "Spectral",
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = FALSE
),group = "SSP3 (RCP7.0)"
%>%
) addPolygons(data = ssp3.p,
group = "SSP3 Suitable") %>%
addLegend(pal = colorNumeric(
palette = "Spectral",
domain = c(0,1),
na.color = "#00000000",
alpha = FALSE,
reverse = TRUE
values = seq(0, 1, by = 0.1), title = "% time", opacity = 1, position = "bottomright",
), labFormat = labelFormat(transform = function(x) sort(x, decreasing = TRUE) * 100)) %>%
addCircleMarkers(lng = pts$x, lat = pts$y,
#clusterOptions = markerClusterOptions(),
radius = 5, weight = 2.5,
group = "Occurrence") %>%
addLayersControl(
baseGroups = c("Current", "SSP1 (RCP2.6)", "SSP2 (RCP4.5)", "SSP3 (RCP7.0)"),
overlayGroups = c("Occurrence", "Current Suitable", "SSP1 Suitable", "SSP2 Suitable", "SSP3 Suitable"),
options = layersControlOptions(collapsed = FALSE)
%>%
) hideGroup(c("Occurrence", "Current Suitable", "SSP1 Suitable", "SSP2 Suitable", "SSP3 Suitable")) %>%
setView(-60, 0, zoom=3)