Beau Larkin Last updated: 27 October, 2025
- Description
- Packages and Libraries
- Sensitivity Analysis Results
- Figure 4 – Manipulated mantid abundance
- Figure 5 – Manipulating abiotic conditions and natural enemies
This script summarizes sensitivity analysis results for MANTRIX using output from the MPG Matrix tool. Figures 4 and 5 visualize predicted percent changes in mantid and trophic guild abundance under alternative scenarios, which considered mantids, their natural enemies, and abiotic conditions. Results are based on paired manipulations of Mantis religiosa abundance, cold snap frequencies, and parasitoid wasp presence/absence.
packages_needed <- c("tidyverse", "colorspace", "knitr", "ggpubr", "Cairo", "rprojroot")
packages_installed <- packages_needed %in% rownames(installed.packages())
if (any(!packages_installed)) install.packages(packages_needed[!packages_installed])
for (pkg in packages_needed) library(pkg, character.only = TRUE)root_path <- function(...) rprojroot::find_rstudio_root_file(...)source(root_path("supplement", "styles.R"))
fig_pt_size <- 3
fig_dodgewidth <- 0.7
guild_labs <- c(
"Invertebrate\nPredators",
"Invertebrate\nHerbivores",
"Pollinators",
"Songbirds",
"Small\nMammals"
)Extract, transform, and load data for later use
sens_path <- root_path("data", "sensitivity_analysis_data")
sens_files <- list.files(sens_path, full.names = TRUE, pattern = "matrix_export")
sens_list <- map(sens_files, read_csv, show_col_types = FALSE)
sens_scenarios <- regmatches(sens_files, regexpr("S\\d+", sens_files))
names(sens_list) <- sens_scenarios
df_names <- c(
"name", "rel_abund", "rel_abund_lc", "rel_abund_uc",
"abund", "abund_lc", "abund_uc",
"pct_change", "pct_change_lc", "pct_change_uc"
)
sens_list <- map(sens_list, function(df) {
colnames(df) <- df_names
df %>%
mutate(
across(starts_with("pct"), ~ round(.x * 100, 1)),
name = case_match(
name,
"Inv. Herbivores" ~ "Invertebrate Herbivores",
"Inv. Predators" ~ "Invertebrate Predators",
"Sm. Mammals" ~ "Small Mammals",
.default = name
)
) %>%
filter(name %in% c("Mantids", "Invertebrate Predators", "Songbirds",
"Small Mammals", "Invertebrate Herbivores", "Pollinators")) %>%
mutate(name = factor(name, levels = c(
"Mantids", "Invertebrate Predators", "Invertebrate Herbivores",
"Pollinators", "Songbirds", "Small Mammals"
), ordered = TRUE)) %>%
select(name, starts_with("pct")) %>%
arrange(name)
})Scenario Labels
scenario_names <- data.frame(
scenario = sens_scenarios,
scenario_labels = c(
"Observed-Low", "Predicted Equilibrium", "Observed-Mid", "Observed-High",
"No Cold Snaps, No Wasps", "Four Cold Snaps, No Wasps",
"No Cold Snaps, 6X Wasps", "Two Cold Snaps, 6X Wasps",
"Four Cold Snaps, 6X Wasps"
)
) %>%
separate_wider_position(scenario, widths = c(1, s_num = 1), cols_remove = FALSE) %>%
mutate(
s_num = as.numeric(s_num),
scenario_labels = fct_reorder(scenario_labels, s_num)
)fig4_data <- bind_rows(
list(S1 = sens_list$S1, S2 = sens_list$S2, S3 = sens_list$S3, S4 = sens_list$S4),
.id = "scenario"
) %>%
left_join(scenario_names, by = join_by(scenario)) %>%
filter(name != "Mantids")
fig4_pal <- sequential_hcl(4, h = c(109, 252), c = c(100, 150, 7), l = c(86, 13), power = c(0.5, 0.9))fig4 <- ggplot(fig4_data, aes(x = name, y = pct_change)) +
geom_hline(yintercept = 0, linewidth = 0.2, linetype = "longdash") +
geom_linerange(
aes(ymin = pct_change_lc, ymax = pct_change_uc, group = scenario_labels),
position = position_dodge(width = fig_dodgewidth), linewidth = 0.3
) +
geom_point(
aes(fill = scenario_labels), shape = 21, size = fig_pt_size,
position = position_dodge(width = fig_dodgewidth)
) +
scale_x_discrete(labels = guild_labs) +
scale_fill_manual(name = "Scenarios 1−4:\nMantid Abundance", values = rev(fig4_pal)) +
labs(x = NULL, y = "Abundance Change (Percent)") +
theme_bgl_s +
guides(fill = guide_legend(position = "inside")) +
theme(legend.position.inside = c(0.86, 0.30), legend.title = element_text(hjust = 0))fig4Fig. 4 Percentage abundance change for target nodes in Scenarios 1-4, each corresponding to incrementally increased M. religiosa abundance based on the pre-invasion baseline FIW. Points show median changes and vertical lines encompass 95% confidence intervals; these are derived from a sensitivity analysis (10,000 permutations). Point color indicates scenario; the color gradient reflects increasing mantid abundance
Cold snaps and parasitoid wasps effects on mantids. A two-panel plot is produced.
fig5_data <- bind_rows(
list(S5 = sens_list$S5, S6 = sens_list$S6, S7 = sens_list$S7,
S8 = sens_list$S8, S9 = sens_list$S9),
.id = "scenario"
) %>%
left_join(scenario_names, by = join_by(scenario)) %>%
separate_wider_delim(scenario_labels, delim = ", ", names = c("winter", "wasps"), cols_remove = FALSE)
fig5_pal <- sequential_hcl(5, h = c(109, 252), c = c(100, 150, 7), l = c(86, 13), power = c(0.5, 0.9))[
order(c(1, 3, 2, 4, 5))
]Panel 1: mantids
fig5_mantis <- fig5_data %>%
filter(name == "Mantids") %>%
ggplot(aes(x = name, y = pct_change)) +
geom_hline(yintercept = 0, linewidth = 0.2, linetype = "longdash") +
geom_linerange(
aes(ymin = pct_change_lc, ymax = pct_change_uc, group = scenario_labels),
position = position_dodge(width = fig_dodgewidth), linewidth = 0.3
) +
geom_point(
aes(fill = scenario_labels), shape = 21, size = fig_pt_size,
position = position_dodge(width = fig_dodgewidth)
) +
scale_fill_manual(name = "Scenario", values = fig5_pal) +
scale_y_continuous(breaks = seq(-100, 25, 25)) +
labs(x = NULL, y = "Abundance Change (Percent)") +
theme_bgl_sPanel 2: target nodes
fig5_targets <- fig5_data %>%
filter(name != "Mantids") %>%
ggplot(aes(x = name, y = pct_change)) +
geom_hline(yintercept = 0, linewidth = 0.2, linetype = "longdash") +
geom_linerange(
aes(ymin = pct_change_lc, ymax = pct_change_uc, group = scenario_labels),
position = position_dodge(width = fig_dodgewidth), linewidth = 0.3
) +
geom_point(
aes(fill = scenario_labels), shape = 21, size = fig_pt_size,
position = position_dodge(width = fig_dodgewidth)
) +
scale_x_discrete(labels = guild_labs) +
scale_fill_manual(name = "Scenarios 5−9: Winter Severity\nand Parasitoid Wasps", values = fig5_pal) +
labs(x = NULL, y = "Abundance Change (Percent)") +
theme_bgl_s +
guides(fill = guide_legend(position = "inside", ncol = 1)) +
theme(legend.position.inside = c(0.58, 0.16), legend.title = element_text(hjust = 1))Arrange panels
fig5 <- ggarrange(
fig5_mantis + theme(legend.position = "none"),
fig5_targets +
scale_y_continuous(
limits = c(-3.4, 5.4),
breaks = c(-3, -1.5, 0, 1.5, 3, 4.5),
labels = c("-3.0", "-1.5", "0", "1.5", "3.0", "4.5")
) +
theme(
axis.title.y = element_blank(),
legend.position.inside = c(0.80, 0.80)
),
nrow = 1,
ncol = 2,
labels = c("a", "b"),
hjust = c(-6.2, -5),
vjust = 2,
font.label = list(size = 12, face = "plain"),
widths = c(0.25, 0.75),
align = "h"
)fig5Fig. 5 Percentage abundance change for a M. religiosa and b target nodes in Scenarios 5-9. Scenarios correspond to altered winter severity and presence/absence of parasitoid wasps and are based on the post-invasion baseline FIW. Points show median changes and vertical lines encompass 95% confidence intervals; these are derived from a sensitivity analysis (10,000 permutations). Point color indicates scenario; the color gradient reflects increasing mantid abundance

