Let’s set up a minimal spatial simulation using slimr
. We will use it to demonstrate making animation of results in gganimate
library(slimr)
library(gganimate)
N <- 100
## minimal spatial sim
spat_sim <- slim_script(
slim_block(initialize(), {
initializeSLiMOptions(dimensionality = "xy")
initializeMutationRate(1e-7)
initializeMutationType("m1", 0.5, "f", 0.0)
initializeGenomicElementType("g1", m1, 1.0)
initializeGenomicElement(g1, 0, 100000 - 1)
initializeRecombinationRate(1e-8)
}),
slim_block(1, early(), {
sim.addSubpop("p1", !!N)
sim.addSubpop("p2", !!N)
p1.setSpatialBounds(c(0, 0, 1, 1))
p2.setSpatialBounds(c(0, 0, 1, 1))
p1.individuals.setSpatialPosition(p1.pointUniform(!!N))
p2.individuals.setSpatialPosition(p2.pointUniform(!!N))
}),
slim_block(1, 1000, late(), {
inds = sim.subpopulations.individuals
location = inds.spatialPosition
## move around a bit
inds.setSpatialPosition(p1.pointReflected(sim.subpopulations.individuals.spatialPosition +
rnorm(inds.size() * 2, 0, 0.01)))
slimr_output_full()
}),
slim_block(modifyChild(), {
child.setSpatialPosition(parent1.spatialPosition)
return(T)
})
)
spat_sim
<slimr_script[4]>
block_init:initialize() {
initializeSLiMOptions(dimensionality = "xy");
initializeMutationRate(1e-07);
initializeMutationType("m1", 0.5, "f", 0);
initializeGenomicElementType("g1", m1, 1);
initializeGenomicElement(g1, 0, 1e+05 - 1);
initializeRecombinationRate(1e-08);
}
block_2:1 early() {
sim.addSubpop("p1", 100);
sim.addSubpop("p2", 100);
p1.setSpatialBounds(c(0, 0, 1, 1));
p2.setSpatialBounds(c(0, 0, 1, 1));
p1.individuals.setSpatialPosition(p1.pointUniform(100));
p2.individuals.setSpatialPosition(p2.pointUniform(100));
}
block_3:1:1000 late() {
inds = sim.subpopulations.individuals;
location = inds.spatialPosition;
inds.setSpatialPosition(p1.pointReflected(sim.subpopulations.individuals.spatialPosition + rnorm(inds.size() * 2, 0, 0.01)));
{sim.outputFull() -> full_output}
}
block_4:1:1000 modifyChild() {
child.setSpatialPosition(parent1.spatialPosition);
return(T);
}
Run that simulation with slim_run
.
spat_run <- slim_run(spat_sim)
Simulation finished with exit status: 0
Success!
Now we can easily extract coordinates:
coords <- slim_extract_full(spat_run$output_data, "coordinates")
coords
# A tibble: 200,000 x 10
generation unique_ind_id pop_id ind_id sex gen_id_1 gen_id_2 x y
<int> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
1 1 p1:i0 p1 i0 H p1:0 p1:1 0.799 0.373
2 1 p1:i1 p1 i1 H p1:2 p1:3 0.185 0.100
3 1 p1:i2 p1 i2 H p1:4 p1:5 0.230 0.636
4 1 p1:i3 p1 i3 H p1:6 p1:7 0.565 0.838
5 1 p1:i4 p1 i4 H p1:8 p1:9 0.234 0.954
6 1 p1:i5 p1 i5 H p1:10 p1:11 0.771 0.391
7 1 p1:i6 p1 i6 H p1:12 p1:13 0.616 0.794
8 1 p1:i7 p1 i7 H p1:14 p1:15 0.246 0.235
9 1 p1:i8 p1 i8 H p1:16 p1:17 0.113 0.207
10 1 p1:i9 p1 i9 H p1:18 p1:19 0.756 0.233
# ... with 199,990 more rows, and 1 more variable: z <dbl>
Animate it!
anim <- ggplot(coords, aes(x, y)) +
geom_point(aes(colour = pop_id)) +
scale_fill_viridis_c() +
coord_equal() +
transition_time(generation) +
shadow_wake(wake_length = 0.01,
alpha = 0.5) +
theme_minimal()
animate(anim, nframes = 1000, fps = 30)