Nature, in Code

Natural Selection

When alleles are selectively neutral (i.e. when they have the same evolutionary fitness), their fate is unpredictable. Whether they will increase or decrease in frequency is due to chance alone. This is evolution by genetic drift.


As soon as an allele has a slightly higher fitness than other alleles, it is very likely that it will increase in frequency and go to fixation. This is evolution by natural selection.


Nevertheless, it is important to keep in mind that in finite population, drift is still acting (as evidenced by the zigzig pattern of the lines). When an allele is rare - as new alleles will be - they might be pushed to extinction before natural selection can sweep them to fixation. In the plot below, the 10 simulations start at p=0.01, but the allele will go to fixation in only a fraction of them:


It's sobering to think about all the highly adaptive mutations that have occurred in the history of life, but that have never made it across the threshold where natural selection could take over and bring them to fixation.


var p;
var N = 2000;
var generations = 200;
var data = [];
var simulations = 10;

function next_generation(simulation_data) {
	var draws = 2 * N;
	var A1 = 0;
	var A2 = 0;
	for (var i = 0; i < draws; i = i + 1) {
	    // change 1.01 to 1 in the line below for genetic drift
		if (Math.random() <= p * 1.01) {
			A1 = A1 + 1;
		else {
			A2 = A2 + 1;
	p = A1/draws;

function simulation(simulation_counter) {
	p = 0.5;
	for (var i = 0; i < generations; i = i + 1) {

for (var i = 0; i < simulations; i = i + 1) {

draw_line_chart(data,"Generation","p",["Population Size:",N,"Generations:",generations]);

Note: the draw_line_chart function is built with D3.js and can be found here.