library(ggplot2)
library(gganimate)
library(reshape2)
library(viridis)
Premise
Ok, so from my last blog post on the Lotka-Volterra competition, I was wondering what would happen if I change my competition parameters over time- how would the dynamics change? Just some code for my future self.
Again, look at my previous post, but I modified the functions:
# c_df is a data.frame containing the competition coefficients above
# N1_0 is the initial population for N1
# N2_0 is the initial population for N2
# timestep is how long we want ot run it for
<- function(c_df, N1_0, N2_0, timestep) {
LV_func # Generate a matrix to keep our records
<- matrix(0, nrow = timestep, ncol = 3)
pop_mat 1] <- seq(1, timestep)
pop_mat[, 1, 2] <- N1_0 # initial first population
pop_mat[1, 3] <- N2_0 # initial second population
pop_mat[
### Competition coefficient
<- c_df["c_11"]
c_11_v <- c_df["c_12"]
c_12_v <- c_df["c_22"]
c_22_v <- c_df["c_21"]
c_21_v
<- 0.01 # Intrinsic growth rate is same for all species
r
for (t in seq(1, timestep - 1)) {
<- c_11_v[t, ]
c_11 <- c_12_v[t, ]
c_12 <- c_22_v[t, ]
c_22 <- c_21_v[t, ]
c_21
<- pop_mat[t, 2] # Get the current population sizes
N1 <- pop_mat[t, 3]
N2
<- r * N1 * (1 - (c_11 * N1 + c_21 * N2))
N1_change <- r * N2 * (1 - (c_22 * N2 + c_12 * N1))
N2_change
+ 1, 2] <- N1 + N1_change
pop_mat[t + 1, 3] <- N2 + N2_change
pop_mat[t
}return(pop_mat)
}
<- 100
timestep
<- expand.grid(
N12_0 N1 = seq(1, 200, length = 15),
N2 = seq(1, 200, length = 15)
)
<- seq(1e-2, 1e-2 * 0.25, length = timestep)
c_11_vec
<- data.frame(
c_df time = seq(1, timestep),
c_11 = c_11_vec,
c_22 = rep(1e-2, timestep),
c_12 = rep(5e-3, timestep),
c_21 = rep(4e-3, timestep)
)
<- do.call(
N12_full
rbind.data.frame,apply(N12_0, 1, function(x) {
LV_func(
c_df,"N1"],
x["N2"],
x[timestep = timestep
)
},simplify = FALSE
)
)### Add an id
$id <- rep(seq(1, nrow(N12_0)), each = timestep)
N12_fullcolnames(N12_full) <- c("time", "N1", "N2", "id")
<- function(c_df, timestep) {
isocline_N1 <- as.numeric(seq(0, 200))
ab
### Competition coefficient
<- c_df["c_11"]
c_11_v <- c_df["c_21"]
c_21_v
<- NULL
isocline_change_df for (t in seq(1, timestep)) {
<- c_11_v[t, ]
c_11 <- c_21_v[t, ]
c_21
<- (1 - (c_21 * ab)) / c_11
isocline
<- cbind.data.frame(N1 = isocline, N2 = ab, time = as.numeric(t))
isocline_change_df[[t]]
}<- do.call(rbind, isocline_change_df)
full return(full)
}
<- function(c_df, timestep) {
isocline_N2 <- as.numeric(seq(0, 200))
ab
### Competition coefficient
<- c_df["c_22"]
c_22_v <- c_df["c_12"]
c_12_v
<- NULL
isocline_change_df for (t in seq(1, timestep)) {
<- c_22_v[t, ]
c_22 <- c_12_v[t, ]
c_12
<- (1 - (c_12 * ab)) / c_22
isocline
<- cbind.data.frame(N1 = ab, N2 = isocline, time = as.numeric(t))
isocline_change_df[[t]]
}<- do.call(rbind, isocline_change_df)
full return(full)
}
<- isocline_N1(c_df, timestep)
isocline1 <- isocline_N2(c_df, timestep) isocline2
That is super-neato!
+ geom_path(
slate data = N12_full,
aes(x = N1, y = N2, group = id, color = time), size = 0.9, alpha = 0.8
+
) transition_reveal(time) +
theme_classic() +
scale_color_viridis(option = "plasma") +
ease_aes("cubic-in-out")