Make it evolve
In the Wright-Fisher model, in each generation, each individual 'samples' its haplotype from a randomly chosen
parent in the generation before. That should be easy to implement, right? Let's write a function to generate a new
generation given the current one (a row of population):
evolve <- function( currentGeneration ) {
parents = sample( 1:N, size = N, replace = TRUE )
return( currentGeneration[parents] )
}
def evolve(current_generation):
parents = np.random.choice(N, size=N, replace=True)
return current_generation[parents]
That was pretty easy! For example if you run this on our starting population:
evolve( population[1,] )
evolve(population[0])
Great, so let's now evolve the population over generations:
for( generation in 2:G ) {
population[generation,] = evolve( population[generation-1,] )
}
for generation in range(1, G):
population[generation] = evolve(population[generation-1])
Look at the result before and after evolution:
layout( matrix( 1:2, nrow = 2 ) )
par( mar = c( 3, 3, 1, 1 ))
plot.haplotypes( haplotypes[population[1,],])
plot.haplotypes( haplotypes[population[G,],])
fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
ax = plot_haplotypes(haplotypes[population[0]], "Gen 0", axes[0])
ax = plot_haplotypes(haplotypes[population[G-1]], f"Gen {G-1}", axes[1])
Wow!
Question. What features of this do you notice?
It's worth emphasising here that there is nothing going on in our model except inheritance. Any structure that appears is purely due to random inheritance.