Public
Edited
Jan 4, 2024
Insert cell
Insert cell
Insert cell
viewof generations = Inputs.range([1, 1000], {value: 100, step: 1, label: "Generations"});
Insert cell
viewof environmentalChangeRate = Inputs.range([0, 1], {value: 0.1, step: 0.01, label: "Environmental Change Rate"});
Insert cell
viewof populationDensity = Inputs.range([1, 10], {value: 5, step: 0.1, label: "Population Density"});
Insert cell
Insert cell
Insert cell
Insert cell
// Simulation Execution Cell with Real-time Visualization
viewof phenotypeFrequencies = {
const initialP = [0.33, 0.33, 0.34]; // Starting frequencies for phenotypes
const data = simulateAdvancedSelection(initialP, generations, environmentalChangeRate, populationDensity);
// Visualization code using D3.js
// The chart should be dynamically updated based on the data
console.log(data);

const width = 800;
const height = 600;

const x = data[0]
const y = data[1]
const line = d3.line().x(d => d).y(d => d);

// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto; height: intrinsic;");

return svg.node();
}
Insert cell
// Function to Simulate Complex Selection with Environmental and Density Changes
function simulateAdvancedSelection(initialP, generations, environmentalChangeRate, populationDensity) {
let p = initialP.slice();
let environmentalFactors = initialP.map(() => 5); // Starting environmental factor for each phenotype
const frequencies = [p];

for (let i = 0; i < generations; i++) {
// Dynamic environmental changes
environmentalFactors = environmentalFactors.map(factor =>
factor + Math.random() * environmentalChangeRate - environmentalChangeRate / 2);

const fitnesses = calculateDensityDependentFitness(p, populationDensity, environmentalFactors);
p = updateMultiplePhenotypes(p, fitnesses);
// Introduce random mutations
p = p.map(freq => Math.max(0, Math.min(1, freq + (Math.random() - 0.5) * 0.01)));

frequencies.push(p.slice());
}
return frequencies;
}

Insert cell
// Function to Calculate Density-Dependent Fitness
function calculateDensityDependentFitness(p, populationDensity, environmentalFactors) {
return p.map((val, idx) => Math.exp(-environmentalFactors[idx] * Math.pow(val, 2) * populationDensity));
}
Insert cell
// Update Frequencies for Multiple Phenotypes
function updateMultiplePhenotypes(p, fitnesses) {
const totalFitness = p.reduce((acc, val, idx) => acc + val * fitnesses[idx], 0);
return p.map((val, idx) => (val * fitnesses[idx]) / totalFitness);
}
Insert cell
// Advanced Fitness Calculation Function
function calculateNonlinearFitness(p, environmentalFactor) {
return Math.exp(-environmentalFactor * Math.pow(p, 2));
}
Insert cell
chart = {
// Chart Setup
const width = 800;
const height = 400;
const margin = {top: 20, right: 30, bottom: 30, left: 40}

const xScale = scaleLinear()
.domain(extent(data, d => d.generation)) // Assuming data has 'generation' field
.range([margin.left, width - margin.right])

const yScale = scaleLinear()
.domain([0, 1]) // Frequency is between 0 and 1
.range([height - margin.bottom, margin.top])

const xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(axisBottom(xScale).ticks(width / 80))

const yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(axisLeft(yScale))

const line = d3.line().x(d => d).y(d => d);
const lineGenerator = line()
.x(d => xScale(d.generation))
.y(d => yScale(d.frequency))
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more