This vignette computes all the figures included in the manuscript associated with the package. This vignette requires loading data frames generated in the first vignette of this package.
# attaching necessary packages library(magrittr) library(sf) library(reshape2) library(ggplot2) library(slfjumps) library(cowplot) library(here) library(dplyr)
Load files generated in the previous vignette
slf <- read.csv(file.path(here(), "data", "lyde_data_v2", "lyde.csv"), h=T) grid_data <- read.csv(file.path(here(), "exported-data", "grid_data.csv"), h=T) centroid <- data.frame(longitude_rounded = -75.675340, latitude_rounded = 40.415240) Jumps <- read.csv(file.path(here(), "exported-data", "jumps.csv")) Jump_clusters <- read.csv(file.path(here(), "exported-data", "jump_clusters.csv")) Thresholds <- read.csv(file.path(here(), "exported-data", "thresholds.csv")) secDiffusion <- read.csv(here("exported-data", "secdiffusion.csv"))
Prepare the states background map
# extract a map of the States and recodes state labels to show the two-letter code rather than the full state name. # obtaining simple feature objects for states and finding centroids for label positioning states <- sf::st_as_sf(maps::map("state", plot = FALSE, fill = TRUE)) %>% st_transform(crs = 4326) sf::sf_use_s2(FALSE) states <- cbind(states, st_coordinates(st_centroid(states))) sf::sf_use_s2(TRUE) # making table key for state 2-letter abbreviations # the vectors state.abb and state.name contains strings of all # US states and abbreviations state_abbr <- tibble(state.name = stringr::str_to_lower(state.name), state.abb) %>% dplyr::left_join(tibble(ID = states$ID), ., by = c(ID = "state.name")) %>% dplyr::mutate(state.abb = tidyr::replace_na(state.abb, "")) # adding 2-letter codes to sf states$code <- state_abbr$state.abb
Map the position of jumps and identify jump clusters per year
map_rarefied <- ggplot(data = states) + geom_sf(data = states, fill = "white") + # positive points geom_point(data = grid_data %>% filter(established == TRUE), aes(x = longitude, y = latitude), col = "lightgrey") + # introduction point annotate("point", x = -75.675340, y = 40.415240, col = "black", shape = 4, size = 3) + # all jumps geom_point(data = Jumps, aes(x = longitude, y = latitude, col = as.factor(year), shape = "All jumps"), size = 3) + # jump clusters geom_point(data = Jump_clusters, aes(x = longitude, y = latitude, shape = "Rarefied jumps"), col = "black", fill = "white", size = 1) + scale_color_manual(name = "Year", values = c("#d53e4f", "#fc8d59", "#f4c957", "#94e65f", "#59a68e", "#27679e"), labels = c("2017", "2018", "2019", "2020", "2021", "2022")) + scale_shape_manual(name = "Jumps", values = c("All jumps" = 19, "Rarefied jumps" = 21)) + coord_sf(xlim = c(-86, -70), ylim = c(36, 44), expand = FALSE) + labs(x = "Longitude", y = "Latitude") + theme(panel.background = element_rect(fill = "white")) map_rarefied ggsave(file.path(here(), "figures", "1A. jumps_map.jpg"), map_rarefied, height = 8, width = 8)
Count how many jumps there are per year
Jump_clusters %<>% mutate(Type = "Rarefied jumps") Jumps %<>% mutate(Type = "All jumps") Clusters_year <- Jump_clusters %>% group_by(year, Type) %>% summarise(n = n()) Jumps_year <- Jumps %>% group_by(year, Type) %>% summarise(n = n()) %>% left_join(Clusters_year, by = "year") %>% mutate(n = n.x - n.y) %>% rename(Type = Type.x) Jumps_total <- bind_rows(Clusters_year, Jumps_year %>% select(year, Type, n)) jumps_plot <- ggplot() + geom_bar(data = Jumps_total, aes(x = year, y = n, fill = as.factor(year), col = as.factor(year), group = Type, alpha = Type), stat = "identity", lwd = .25, show.legend = F) + scale_fill_manual(values = c("#d53e4f", "#fc8d59", "#f4c957", "#94e65f", "#59a68e", "#27679e")) + scale_color_manual(values = c("#d53e4f", "#fc8d59", "#f4c957", "#94e65f", "#59a68e", "#27679e")) + scale_alpha_manual(values = c(1, 0)) + xlab("Year") + ylab("Number of jumps") + theme_classic() + scale_x_continuous(breaks = seq(2017, 2022, by = 1)) + theme(text = element_text(size = 10)) jumps_plot ggsave(file.path(here(), "figures", "1B. number of jumps.jpg"), jumps_plot, height = 2.5, width = 4)
Show the distance between the invasion front and jumps every year. This variable is stored in the DistToSLF column.
MeanDist_jump <- ggplot() + geom_boxplot(data = Jumps, show.legend = F, aes(x = Type, y = DistToSLF/1000, col = as.factor(year), fill = as.factor(year)), alpha = 0.7) + geom_boxplot(data = Jump_clusters, show.legend = F, aes(x = Type, y = DistToSLF/1000, col = as.factor(year), fill = as.factor(year)), alpha = 0, outlier.alpha = 0.7) + scale_color_manual(values = c("#d53e4f", "#fc8d59", "#f4c957", "#94e65f", "#59a68e", "#27679e")) + scale_fill_manual(values = c("#d53e4f", "#fc8d59", "#f4c957", "#94e65f", "#59a68e", "#27679e")) + labs(x = "Dataset", y = "Distance from the invasion front (km)") + theme_classic() MeanDist_jump ggsave(file.path(here(), "figures", "1C. jump_distances.jpg"), MeanDist_jump, height = 2.5, width = 4)
fig1 <- ggdraw() + draw_plot(map_rarefied, x = 0, y = .33, width = 1, height = .66) + draw_plot(jumps_plot, 0, 0, .5, .33) + draw_plot(MeanDist_jump, .5, 0, .5, .33) + draw_plot_label(c("(a)", "(b)", "(c)"), c(0, 0, 0.5), c(1, 0.35, 0.35), size = 15) + theme(plot.background = element_rect(fill="#FFFFFF", color = NA)) fig1 ggsave(file.path(here(), "figures", "1. jump_description.jpg"), fig1, height = 10, width = 10)
To estimate the spread of the SLF, we extract for each year the radius of the invasion in each sector. We can look at how the radius of the invasion increases over time, when differentiating diffusive spread and jump dispersal.
sectors_used = 16 thresholdSectors <- slfjumps::attribute_sectors(Thresholds %>% select(year, latitude, longitude, DistToIntro), nb_sectors = sectors_used, centroid = c(-75.67534, 40.41524)) jumpSectors <- slfjumps::attribute_sectors(Jumps %>% select(year, latitude, longitude, DistToIntro), nb_sectors = sectors_used, centroid = c(-75.67534, 40.41524)) thresholdMaxSector <- thresholdSectors %>% group_by(year, sectors_nb) %>% summarise(maxDistToIntro = max(DistToIntro)) allMaxSector <- bind_rows(thresholdSectors, jumpSectors) %>% group_by(year, sectors_nb) %>% summarise(maxDistToIntro = max(DistToIntro)) radiusData <- bind_rows(allMaxSector %>% mutate(Type = "All spread"), thresholdMaxSector %>% mutate(Type = "Invasion front")) invasionRadius <- ggplot(stat = "identity") + geom_boxplot(data = radiusData, aes(x = as.factor(year), y = maxDistToIntro, fill = Type)) + scale_fill_manual(name = "Type", values = c("All spread" = "white", "Invasion front" = "gray60")) + theme_classic() + labs(x = "Year", y = "Distance to Introduction") + theme(legend.title = element_text(size = 20), legend.text = element_text(size = 16), legend.key.size = unit(2, "lines"), axis.title = element_text(size = 18), axis.text = element_text(size = 12)) invasionRadius ggsave(file.path(here(), "figures", "2. invasionRadius.jpeg"), invasionRadius, height = 6, width = 10)
Map the points identified as secondary diffusion around dispersal jumps.
# Reverse the order of data frames supplied to geom_point secDiff_map <- ggplot() + geom_point(data = grid_data %>% filter(established == TRUE), aes(x = longitude, y = latitude), col = "lightgrey") + geom_point(data = secDiffusion %>% arrange(desc(year)), aes(x = longitude, y = latitude, col = as.factor(year)), stroke = 2, size = 4) + geom_point(data = Jump_clusters %>% arrange(desc(year)), aes(x = longitude, y = latitude, col = as.factor(year), fill = as.factor(year)), color = "black", shape = 21, stroke = 0.5, size = 3.5) + scale_color_manual(values = c( "#f4c957", "#94e65f", "#59a68e", "#27679e")) + scale_fill_manual(values = c( "#d53e4f", "#fc8d59", "#f4c957", "#94e65f", "#59a68e", "#27679e")) + labs(x = "Longitude", y = "Latitude") + theme(legend.position = "right", text = element_text(size = 10), panel.background = element_rect(fill = "white"), legend.key = element_rect(fill = "white"), legend.title = element_text(size = 20), legend.text = element_text(size = 16), legend.key.size = unit(2, "lines"), axis.title = element_text(size = 18), axis.text = element_text(size = 12)) + geom_sf(data = states, alpha = 0) + coord_sf(xlim = c(-85.25, -71), ylim = c(36.5, 43)) + guides(colour = guide_legend(paste0("Secondary", "\n", "Diffusion")), fill = guide_legend("Rarefied jumps")) secDiff_map ggsave(file.path(here(), "figures", "3. secDiff_map.jpeg"), secDiff_map, height = 8, width = 15)
Count how many jumps were followed by secondary diffusion
# select jumps for which we have data for year n+1 Jumps_2021 <- Jumps %>% filter(year %in% c(2014:2021)) %>% mutate(secDiff = NA) # select diffusion points to check if the jump was already caught up by the # diffusive spread the year after diff_secDiff <- setdiff(grid_data %>% filter(established == T), Jumps %>% select(year, latitude, longitude, established, DistToIntro)) # remove jumps diff <- setdiff(diff_secDiff, secDiffusion %>% select(-theta)) # remove secondary diffusion for (jump in 1:length(Jumps_2021$DistToIntro)){ #for each jump # is this jump within 15 km of any diffusion point the year after? ie. caught up by diffusion testDiff <- diff %>% filter(year %in% c(min(Jumps_2021$year), Jumps_2021$year[jump]+1)) pairwise_dist <- geosphere::distGeo(testDiff[,c(3,2)], Jumps_2021[jump,c(4,3)])/1000 if (min(pairwise_dist) < 15){ Jumps_2021$secDiff[jump] = "caught up" } else { # is there secondary diffusion within 15 km the year after? # calculate pairwise distance with secDiff the year after testSecDiff <- secDiffusion %>% filter(year == Jumps_2021$year[jump]+1) if (dim(testSecDiff)[1] > 0){ # check distances pairwise_dist <- geosphere::distGeo(testSecDiff[,c(4,3)], Jumps_2021[jump,c(4,3)])/1000 Jumps_2021$secDiff[jump] = ifelse(min(pairwise_dist) < 15, "yes", "no") } } } Jumps_secDiff <- Jumps_2021 %>% group_by(year, secDiff) %>% summarise(count = n()) %>% # filter(secondary_diffusion %in% c("yes", "no", "swallowed")) %>% ungroup() Jumps_secDiff$secDiff <- factor(Jumps_secDiff$secDiff, levels = c("caught up", "no", "yes")) #Bar Plot Jumps_secDiff_plot <- ggplot() + geom_bar(data = Jumps_secDiff, aes(x = as.factor(year), y = count, group = secDiff, fill = as.factor(year), col = as.factor(year), alpha = secDiff), lwd = .25, #position = "dodge" stat = "identity") + scale_fill_manual(values = c("#d53e4f", "#fc8d59", "#f4c957", "#94e65f", "#59a68e", "#27679e"), guide = "none") + scale_color_manual(values = c("#d53e4f", "#fc8d59", "#f4c957", "#94e65f", "#59a68e", "#27679e"), guide = "none") + scale_alpha_manual(values = c(0.3, 0, 1)) + theme_classic() + xlab("Year of Jump") + ylab("Number of Jumps") + guides(alpha = guide_legend( paste0("Followed by", "\n", "secondary diffusion"), override.aes = list(fill = "black", color = "black", linetype = 1, shape = 21))) + theme(legend.title = element_text(size = 20), legend.text = element_text(size = 16), legend.key.size = unit(2, "lines"), axis.title = element_text(size = 18), axis.text = element_text(size = 12)) Jumps_secDiff_plot ggsave(file.path(here(), "figures", "3B. secDiff_bar.jpeg"), Jumps_secDiff_plot, height = 5, width = 8)
secDiff_graphs_combined <- cowplot::ggdraw() + cowplot::draw_plot(secDiff_map, 0, .33, 1, 0.66) + cowplot::draw_plot(Jumps_secDiff_plot, 0, 0, 1, 0.33) + cowplot::draw_plot_label(c("(a)", "(b)"), c(0.06, 0.06), c(0.90, 0.33), size = 25) secDiff_graphs_combined ggsave(file.path(here(), "figures", "3. secDiff_combined.jpeg"), secDiff_graphs_combined, height = 13, width = 13)
Visualize all results, faceted by year
# Make a single object for the map jumps_wrapper_map <- dplyr::bind_rows(grid_data %>% filter(established == F) %>% dplyr::mutate(Type = "SLF not established"), grid_data %>% filter(established == T) %>% dplyr::mutate(Type = "SLF established"), Thresholds %>% dplyr::mutate(Type = "Diffusion threshold"), Jumps %>% dplyr::mutate(Type = "Jump"), secDiffusion %>% dplyr::mutate(Type = "Secondary diffusion")) facetedResults <- ggplot(data = states) + geom_point(data = jumps_wrapper_map, aes(x = longitude, y = latitude, col = Type)) + geom_sf(data = states, alpha = 0) + facet_wrap(~year) + geom_text(data = states, aes(X, Y, label = code), size = 2) + theme(legend.position = "bottom") + theme_classic() + scale_color_manual(values = c("blue", "green", "orange", "gray30", "gray90")) + xlab("Longitude") + ylab("Latitude") + labs(col = "Identification") + coord_sf(xlim = c(-82, -72), ylim = c(38, 43), expand = FALSE) + theme(legend.position = "right", text = element_text(size = 10), panel.background = element_rect(fill = "white"), legend.key = element_rect(fill = "white"), legend.title = element_text(size = 20), legend.text = element_text(size = 16), legend.key.size = unit(2, "lines"), axis.title = element_text(size = 18), axis.text = element_text(size = 12)) facetedResults ggsave(file.path(here(), "figures", "4. faceted_results.jpeg"), facetedResults, height = 12, width = 20)
Facet A: Overview of all SLF surveys
# plot US map mapUS <- ggplot(data = states) + geom_point(data = grid_data %>% filter(established == FALSE), aes(x = longitude, y = latitude), col = "gray", size = 1) + geom_point(data = grid_data %>% filter(established == TRUE), aes(x = longitude, y = latitude), col = "black", size = 1) + geom_sf(alpha = 0) + labs(x = "Longitude", y = "Latitude") + theme_classic() + theme(legend.position = "bottom", legend.key = element_rect(fill = "white", colour = NA)) mapUS # save it ggsave(file.path(here(), "figures", "S1A. points_all.jpg"), mapUS, width = 6, height = 6)
Facet B: Zoomed map on established SLF
# create a variable for a meaningful legend grid_data %<>% mutate(SLF = ifelse(established == T, "Present", "Absent")) # plot zoomed map zoomedMap <- ggplot(data = states) + geom_point(data = grid_data %>% filter(established == FALSE), aes(x = longitude, y = latitude), col = "gray", size = 1) + geom_point(data = grid_data %>% filter(established == TRUE), aes(x = longitude, y = latitude), col = "black", size = 1) + geom_sf(alpha = 0) + labs(x = "Longitude", y = "Latitude") + coord_sf(xlim = c(-86, -70), ylim = c(36, 44)) + theme_classic() + theme(legend.position="bottom", legend.key = element_rect(fill = "white", colour = NA)) zoomedMap # save it ggsave(file.path(here(), "figures", "S1B. zoomed_points.jpg"), zoomedMap, width = 6, height = 6)
Show the evolution of the sampling effort and jump occurrences over time
surveys <- as.data.frame(table(slf$bio_year)) %>% mutate(Type = "Surveys") %>% rename(year = Var1, n = Freq) points <- as.data.frame(table(grid_data$year)) %>% mutate(Type = "Points") %>% rename(year = Var1, n = Freq) positives <- grid_data %>% filter(established == T) positive_points <- as.data.frame(table(positives$year)) %>% mutate(Type = "Positive points") %>% rename(year = Var1, n = Freq) jumps <- Jumps %>% count(year) %>% mutate(Type = "Dispersal jumps") clusters <- Jump_clusters %>% count(year) %>% mutate(Type = "Jump clusters") effort <- rbind(surveys, points, positive_points, jumps, clusters) effort$Type <- factor(effort$Type, levels = c("Surveys", "Points", "Positive points", "Dispersal jumps", "Jump clusters")) effort_plot <- ggplot() + geom_point(data = effort, aes(x = year, y = log(n), shape = Type), size = 3) + theme_classic() + xlab("Year") + ylab("log(count)") effort_plot ggsave(file.path(here(), "figures", "S2. number of surveys.jpg"), effort_plot, width = 7, height = 5)
-- end of vignette --
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.