Getting summary sample data from MERMAID
This code downloads summary sample event data from MERMAID, using the mermaidr package (documentation can be found at https://data-mermaid.github.io/mermaidr/). The summary sample events contain all surveys (i.e. sample events) that have permissions of “public summary” or “public”.
rm(list = ls()) #remove past stored objects
options(scipen = 999) #turn off scientific notation
#### Load packages and libraries ####
## If this is the first time using mermaidr, install the package through "remotes"
# install.packages("remotes")
# remotes::install_github("data-mermaid/mermaidr")
# install.packages("tidyverse")
# install.packages("plotly")
# install.packages("htmlwidgets")
library(mermaidr) #package to download data from datamermaid.org
library(tidyverse) #package that makes it easier to work with data
library(plotly) #for interactive plotting
library(htmlwidgets) #for saving plots at html files
#### Get data from MERMAID for creating aggregate visualizations ####
allMermaidSampEventsTBL <- mermaidr::mermaid_get_summary_sampleevents()
Histogram - hard coral cover (%) by survey
This code creates a histogram showing the variability in % hard coral cover across surveys (sample events), with different colored bars for <10% coral cover (net-negative carbonate production), >10% but <30% coral cover (net-positive carbonate production), and >30% coral cover (maintains biodiversity, complexity, and fisheries production). It also includes code to show the total number of surveys (i.e. sample events in MERMAID) at the top of the plot. In the first step, we calculate average % hard coral cover for each survey across all four benthic protocols that measure % hard coral cover: benthic PIT, benthic LIT, benthic PQT, and bleaching surveys.
### Combine all benthic data - get averages across 4 protocols
hardCoralTBL <- allMermaidSampEventsTBL %>%
rowwise() %>%
mutate(all_percent_cover_avg_Hard_coral =
mean(c(`benthicpit_percent_cover_benthic_category_avg_Hard coral`,
`benthiclit_percent_cover_benthic_category_avg_Hard coral`,
`benthicpqt_percent_cover_benthic_category_avg_Hard coral`,
quadrat_benthic_percent_percent_hard_avg_avg), na.rm = T)) %>%
ungroup() %>%
filter(!is.na(all_percent_cover_avg_Hard_coral))
# Create the histogram to get bin data to assign colors
hist_data <- hist(hardCoralTBL$all_percent_cover_avg_Hard_coral,
breaks = seq(0, 100, by = 2),
plot = FALSE) #In this function a 4 will be in the first bin
# Assign colors based on bin order
bin_colors <- sapply(seq_along(hist_data$counts), function(i) {
if (i <= 5) {
return('#d13823')
} else if (i > 5 && i <= 15) {
return('#f3a224')
} else {
return('#277d1d')
}
})
# Create the histogram using plotly
hardCoralAggHist <-
plot_ly(x = hardCoralTBL$all_percent_cover_avg_Hard_coral,
type = 'histogram',
xbins = list(start = 0, size = 2, end = 100),
marker = list(color = bin_colors), height = 450) %>%
config(displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = c('zoom','pan', 'select', 'zoomIn', 'zoomOut',
'autoScale', 'resetScale', 'lasso2d',
'hoverClosestCartesian', 'hoverCompareCartesian')) %>%
layout(bargap = 0.1,
shapes = list(
list(type = "line",
x0 = 10, x1 = 10, y0 = 0, y1 = 1, yref = "paper",
line = list(color = "black", dash = "dot")),
list(type = "line",
x0 = 30, x1 = 30, y0 = 0, y1 = 1, yref = "paper",
line = list(color = "black", dash = "dot"))
),
xaxis = list(title = "% Hard Coral Cover",
linecolor = "black",
linewidth = 2,
tickvals = seq(0, 100, by = 10), # Set x-axis tick values
ticktext = seq(0, 100, by = 10)),
yaxis = list(title = "Number of surveys",
linecolor = "black", # Set the y-axis line color to black
linewidth = 2),
annotations = list(
list(x = 0, y = 1.15, text = "HARD CORAL COVER", showarrow = FALSE,
xref = 'paper', yref = 'paper', xanchor = 'left', yanchor = 'top',
font = list(size = 20)),
list(x = 0, y = 1.08,
text = paste0(length(hardCoralTBL$all_percent_cover_avg_Hard_coral),
" Surveys"),
showarrow = FALSE,
xref = 'paper', yref = 'paper', xanchor = 'left', yanchor = 'top',
font = list(size = 12))
),
margin = list(t = 50, b = 75)) # Increase top margin to create more space for title and subtitle
# Visualize the plot
hardCoralAggHist
Time series - % benthic cover by year and category
Stacked barplot showing the percent cover (y-axis) by year (x-axis) for each of 11 high-level benthic categories: Hard coral, Bare substrate, Crustose coralline algae, Rubble, Cyanobacteria, Seagrass, Sand, Macroalgae, Turf algae, Soft coral, Other invertebrates. In the first step, average % cover is calculated for each of the 11 categories across the three benthic protocols that collect data for those categories (benthic PIT, benthic LIT, benthic PQT).
### Get average % cover for 11 broad categories across three survey protocols
benthicAvgTBL <- allMermaidSampEventsTBL %>%
rowwise() %>%
mutate(all_percent_cover_avg_Hard_coral =
mean(c(`benthicpit_percent_cover_benthic_category_avg_Hard coral`,
`benthiclit_percent_cover_benthic_category_avg_Hard coral`,
`benthicpqt_percent_cover_benthic_category_avg_Hard coral`),
na.rm = T),
all_percent_cover_avg_Bare_substrate =
mean(c(`benthicpit_percent_cover_benthic_category_avg_Bare substrate`,
`benthiclit_percent_cover_benthic_category_avg_Bare substrate`,
`benthicpqt_percent_cover_benthic_category_avg_Bare substrate`),
na.rm = T),
all_percent_cover_avg_Crustose_coralline_algae =
mean(c(`benthicpit_percent_cover_benthic_category_avg_Crustose coralline algae`,
`benthiclit_percent_cover_benthic_category_avg_Crustose coralline algae`,
`benthicpqt_percent_cover_benthic_category_avg_Crustose coralline algae`),
na.rm = T),
all_percent_cover_avg_Rubble =
mean(c(benthicpit_percent_cover_benthic_category_avg_Rubble,
benthiclit_percent_cover_benthic_category_avg_Rubble,
benthicpqt_percent_cover_benthic_category_avg_Rubble),
na.rm = T),
all_percent_cover_avg_Cyanobacteria =
mean(c(benthicpit_percent_cover_benthic_category_avg_Cyanobacteria,
benthiclit_percent_cover_benthic_category_avg_Cyanobacteria,
benthicpqt_percent_cover_benthic_category_avg_Cyanobacteria),
na.rm = T),
all_percent_cover_avg_Seagrass =
mean(c(benthicpit_percent_cover_benthic_category_avg_Seagrass,
benthiclit_percent_cover_benthic_category_avg_Seagrass,
benthicpqt_percent_cover_benthic_category_avg_Seagrass),
na.rm = T),
all_percent_cover_avg_Sand =
mean(c(benthicpit_percent_cover_benthic_category_avg_Sand,
benthiclit_percent_cover_benthic_category_avg_Sand,
benthicpqt_percent_cover_benthic_category_avg_Sand),
na.rm = T),
all_percent_cover_avg_Macroalgae =
mean(c(benthicpit_percent_cover_benthic_category_avg_Macroalgae,
benthiclit_percent_cover_benthic_category_avg_Macroalgae,
benthicpqt_percent_cover_benthic_category_avg_Macroalgae),
na.rm = T),
all_percent_cover_avg_Turf_algae =
mean(c(`benthicpit_percent_cover_benthic_category_avg_Turf algae`,
`benthiclit_percent_cover_benthic_category_avg_Turf algae`,
`benthicpqt_percent_cover_benthic_category_avg_Turf algae`),
na.rm = T),
all_percent_cover_avg_Soft_coral =
mean(c(`benthicpit_percent_cover_benthic_category_avg_Soft coral`,
`benthiclit_percent_cover_benthic_category_avg_Soft coral`,
`benthicpqt_percent_cover_benthic_category_avg_Soft coral`),
na.rm = T),
all_percent_cover_avg_Other_invertebrates =
mean(c(`benthicpit_percent_cover_benthic_category_avg_Other invertebrates`,
`benthiclit_percent_cover_benthic_category_avg_Other invertebrates`,
`benthicpqt_percent_cover_benthic_category_avg_Other invertebrates`),
na.rm = T),
all_percent_cover_sample_unit_count =
sum(c(benthicpit_sample_unit_count,
benthiclit_sample_unit_count,
benthicpqt_sample_unit_count),
na.rm = T)) %>%
ungroup() %>%
mutate(year = year(sample_date)) %>%
filter(all_percent_cover_sample_unit_count > 0)
benthicSummYearCatTBL <- benthicAvgTBL %>%
group_by(year) %>%
summarise(
Avg_Hard_coral = mean(all_percent_cover_avg_Hard_coral,
na.rm = T),
Avg_Bare_substrate = mean(all_percent_cover_avg_Bare_substrate,
na.rm = T),
Avg_Crustose_coralline_algae = mean(all_percent_cover_avg_Crustose_coralline_algae,
na.rm = T),
Avg_Rubble = mean(all_percent_cover_avg_Rubble,
na.rm = T),
Avg_Cyanobacteria = mean(all_percent_cover_avg_Cyanobacteria,
na.rm = T),
Avg_Seagrass = mean(all_percent_cover_avg_Seagrass,
na.rm = T),
Avg_Sand = mean(all_percent_cover_avg_Sand,
na.rm = T),
Avg_Macroalgae = mean(all_percent_cover_avg_Macroalgae,
na.rm = T),
Avg_Turf_algae = mean(all_percent_cover_avg_Turf_algae,
na.rm = T),
Avg_Soft_coral = mean(all_percent_cover_avg_Soft_coral,
na.rm = T),
Avg_Other_invertebrates = mean(all_percent_cover_avg_Other_invertebrates,
na.rm = T)) %>%
ungroup() %>%
filter(year > 1900)
# Create the histogram using plotly
benthicTimeSeriesPercBarplot <-
plot_ly(data = benthicSummYearCatTBL,
x = ~year,
y = ~Avg_Hard_coral,
type = 'bar',
name = "Hard coral",
marker = list(color = "#498fc9"),
height = 450) %>%
add_trace(y = ~Avg_Bare_substrate,
name = "Bare substrate",
marker = list(color = "#f2f3f3")) %>%
add_trace(y = ~Avg_Crustose_coralline_algae,
name = "Crustose coralline algae",
marker = list(color = "#fbd7d5")) %>%
add_trace(y = ~Avg_Rubble,
name = "Rubble",
marker = list(color = "#f5f6af")) %>%
add_trace(y = ~Avg_Cyanobacteria,
name = "Cyanobacteria",
marker = list(color = "#870e00")) %>%
add_trace(y = ~Avg_Seagrass,
name = "Seagrass",
marker = list(color = "#4d4d4d")) %>%
add_trace(y = ~Avg_Sand,
name = "Sand",
marker = list(color = "#c1b180")) %>%
add_trace(y = ~Avg_Macroalgae,
name = "Macroalgae",
marker = list(color = "#b2b000")) %>%
add_trace(y = ~Avg_Turf_algae,
name = "Turf algae",
marker = list(color = "#d9eea8")) %>%
add_trace(y = ~Avg_Soft_coral,
name = "Soft coral",
marker = list(color = "#9ce5fa")) %>%
add_trace(y = ~Avg_Other_invertebrates,
name = "Other invertebrates",
marker = list(color = "#4e4e4e")) %>%
config(displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = c('zoom','pan', 'select', 'zoomIn', 'zoomOut',
'autoScale', 'resetScale', 'lasso2d',
'hoverClosestCartesian',
'hoverCompareCartesian')) %>%
layout(barmode = "stack",
bargap = 0.1,
yaxis = list(title = "Benthic % cover",
linecolor = "black",
linewidth = 2,
hoverformat = '.2f',
tickvals = seq(0, 100, by = 10), # Set y-axis tick values
ticktext = seq(0, 100, by = 10)),
xaxis = list(title = "Year",
linecolor = "black", # Set the x-axis line color to black
linewidth = 2),
annotations = list(
list(x = 0, y = 1.15, text = "BENTHIC % COVER (PIT)", showarrow = FALSE,
xref = 'paper', yref = 'paper', xanchor = 'left', yanchor = 'top',
font = list(size = 20)),
list(x = 0, y = 1.06,
text = paste0(
nrow(
benthicAvgTBL %>%
filter(
!is.na(all_percent_cover_avg_Hard_coral))),
" Surveys"),
showarrow = FALSE,
xref = 'paper', yref = 'paper', xanchor = 'left', yanchor = 'top',
font = list(size = 12))
),
legend = list(orientation = "h", xanchor = "center", x = 0.5, y = -0.2),
margin = list(t = 50, b = 75)) # Increase top margin to create more space for title and subtitle
# Visualize the plot
benthicTimeSeriesPercBarplot
Stacked Single Barplot - % cover by category (single survey)
Code to create a single stacked barplot showing the percent cover (y-axis), with different colors representing 11 broad level benthic categories: Hard coral, Bare substrate, Crustose coralline algae, Rubble, Cyanobacteria, Seagrass, Sand, Macroalgae, Turf algae, Soft coral, Other invertebrates. This code shows an example with a single sample event (i.e. survey) but could be adapted to apply to multiple surveys and sites. As with the previous plot, this visualization uses the average % cover for each of the 11 categories across three benthic protocols (benthic PIT, benthic LIT, benthic PQT).
benthicSingleSeTBL <- benthicAvgTBL %>%
select(project, site, starts_with("all_percent_cover_"))
## create fixed label and color mapping for the benthic categories
benthicLabels <- str_to_sentence(
gsub(
x = gsub(
x = colnames(
benthicSingleSeTBL %>%
select(-all_percent_cover_sample_unit_count)),
pattern = "all_percent_cover_avg_",
replacement = ""),
pattern = "_",
replacement = " "))
benthicColorMap <- setNames(
object = c("#498fc9", "#f2f3f3", "#fbd7d5", "#f5f6af", "#870e00", "#4d4d4d", "#c1b180", "#b2b000", "#d9eea8", "#9ce5fa", "#4e4e4e"),
nm = levels(benthicLabels))
# Create the histogram using plotly
benthicPercSingleSeBarplot <-
plot_ly(data = benthicSingleSeTBL[1,],
x = 1,
y = ~all_percent_cover_avg_Hard_coral,
type = 'bar',
name = paste0("Hard coral (", benthicSingleSeTBL$all_percent_cover_avg_Hard_coral[1], "%)"),
marker = list(color = "#498fc9"),
height = 450,
width = 500) %>%
add_trace(y = ~all_percent_cover_avg_Bare_substrate,
name = paste0("Bare substrate (", benthicSingleSeTBL$all_percent_cover_avg_Bare_substrate[1], "%)"),
marker = list(color = "#f2f3f3")) %>%
add_trace(y = ~all_percent_cover_avg_Crustose_coralline_algae,
name = paste0("Crustose coralline algae (", benthicSingleSeTBL$all_percent_cover_avg_Crustose_coralline_algae[1], "%)"),
marker = list(color = "#fbd7d5")) %>%
add_trace(y = ~all_percent_cover_avg_Rubble,
name = paste0("Rubble (", benthicSingleSeTBL$all_percent_cover_avg_Rubble[1], "%)"),
marker = list(color = "#f5f6af")) %>%
add_trace(y = ~all_percent_cover_avg_Cyanobacteria,
name = paste0("Cyanobacteria (", benthicSingleSeTBL$all_percent_cover_avg_Cyanobacteria[1], "%)"),
marker = list(color = "#870e00")) %>%
add_trace(y = ~all_percent_cover_avg_Seagrass,
name = paste0("Seagrass (", benthicSingleSeTBL$all_percent_cover_avg_Seagrass[1], "%)"),
marker = list(color = "#4d4d4d")) %>%
add_trace(y = ~all_percent_cover_avg_Sand,
name = paste0("Sand (", benthicSingleSeTBL$all_percent_cover_avg_Sand[1], "%)"),
marker = list(color = "#c1b180")) %>%
add_trace(y = ~all_percent_cover_avg_Macroalgae,
name = paste0("Macroalgae (", benthicSingleSeTBL$all_percent_cover_avg_Macroalgae[1], "%)"),
marker = list(color = "#b2b000")) %>%
add_trace(y = ~all_percent_cover_avg_Turf_algae,
name = paste0("Turf algae (", benthicSingleSeTBL$all_percent_cover_avg_Turf_algae[1], "%)"),
marker = list(color = "#d9eea8")) %>%
add_trace(y = ~all_percent_cover_avg_Soft_coral,
name = paste0("Soft coral (", benthicSingleSeTBL$all_percent_cover_avg_Soft_coral[1], "%)"),
marker = list(color = "#9ce5fa")) %>%
add_trace(y = ~all_percent_cover_avg_Other_invertebrates,
name = paste0("Other invertebrates (", benthicSingleSeTBL$all_percent_cover_avg_Other_invertebrates[1], "%)"),
marker = list(color = "#4e4e4e")) %>%
config(displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = c('zoom','pan', 'select', 'zoomIn', 'zoomOut',
'autoScale', 'resetScale', 'lasso2d',
'hoverClosestCartesian',
'hoverCompareCartesian')) %>%
layout(barmode = "stack",
bargap = 0,
yaxis = list(title = "",
linecolor = "black",
linewidth = 2,
range = c(0,100),
tickvals = seq(0, 100, by = 10), # Set y-axis tick values
ticksuffix = "%"),
xaxis = list(title = "",
linecolor = "black", # Set the x-axis line color to black
linewidth = 2,
showticklabels=FALSE),
annotations = list(
list(x = 0, y = 1.15, text = "BENTHIC % COVER", showarrow = FALSE,
xref = 'paper', yref = 'paper', xanchor = 'left', yanchor = 'top',
font = list(size = 20)),
list(x = 0, y = 1.08,
text = paste(benthicSingleSeTBL$all_percent_cover_sample_unit_count[1],
" Sample units"),
showarrow = FALSE,
xref = 'paper', yref = 'paper', xanchor = 'left', yanchor = 'top',
font = list(size = 12))
),
margin = list(t = 50, b = 75))
# Visualize the plot
benthicPercSingleSeBarplot
Donut plot - % cover from bleaching protocol (single survey)
This code creates a donut plot showing the percent cover of the three broad benthic categories (represented by different colors) that are estimated in the quadrat section of the bleaching protocol. Since this protocol does not include all 11 of the benthic categories represented in the other benthic protocols (see above), I thought it would be worthwhile to show a separate example of what can be done with a smaller number of categories.
### Bleaching % benthic cover data - single sample event
bleachPercBenthicTBL <- allMermaidSampEventsTBL %>%
select(project, site, starts_with("quadrat_benthic_percent_")) %>%
replace(is.na(.), 0) %>%
filter(quadrat_benthic_percent_quadrat_count_avg > 0) %>%
mutate(TotalQuadrats = quadrat_benthic_percent_quadrat_count_avg*quadrat_benthic_percent_sample_unit_count,
quadrat_benthic_percent_percent_other_avg_avg = 100 -
quadrat_benthic_percent_percent_hard_avg_avg -
quadrat_benthic_percent_percent_soft_avg_avg -
quadrat_benthic_percent_percent_algae_avg_avg) %>%
filter(project == "Barefoot Manta Bleaching Surveys 2023" &
site == "Sunrise Beach")
## create fixed label and color mapping for the bleaching benthic categories
## Assigning labels based on the percent columns
bleachBenthicLabels <- c("Hard coral", "Soft coral", "Algae", "Other")
bleachBenthicColorMap <- setNames(
object = c("#498fc9", "#9ce5fa", "#b6b400", "#b4b4b4"),
nm = bleachBenthicLabels)
bleachingBenthicCoverDonutPlot <-
plot_ly(data = bleachPercBenthicTBL,
labels = paste0(
bleachBenthicLabels,
" (",
as.numeric(
bleachPercBenthicTBL[1,
colnames(
bleachPercBenthicTBL %>%
select(
starts_with(
"quadrat_benthic_percent_percent")))]),
"%)"),
values = as.numeric(
bleachPercBenthicTBL[1,
colnames(
bleachPercBenthicTBL %>%
select(
starts_with(
"quadrat_benthic_percent_percent")))]),
textposition = 'inside',
textinfo = 'percent',
height = 450) %>%
add_pie(hole = 0.5,
marker = list(colors = bleachBenthicColorMap,
line = list(color = '#FFFFFF', width = 1))) %>%
config(displayModeBar = TRUE,
displaylogo = FALSE,
modeBarButtonsToRemove = c('zoom','pan', 'select', 'zoomIn', 'zoomOut',
'autoScale', 'resetScale', 'lasso2d',
'hoverClosestPie')) %>%
layout(xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
annotations = list(
list(x = 0, y = 1.15, text = "BLEACHING - % BENTHIC COVER", showarrow = FALSE,
xref = 'paper', yref = 'paper', xanchor = 'left', yanchor = 'top',
font = list(size = 20)),
list(x = 0, y = 1.08,
text = paste0(bleachPercBenthicTBL$TotalQuadrats[1],
" Quadrats"),
showarrow = FALSE,
xref = 'paper', yref = 'paper', xanchor = 'left', yanchor = 'top',
font = list(size = 12))),
margin = list(t = 50, b = 75)) # Increase top margin to create more space for title and subtitle
# Visualize the plot
bleachingBenthicCoverDonutPlot