Simulates the long term behavior of the logistic map, xn+1 = rxn(1-xn).
x-axis varies the parameter r, y-axis shows the value of the function after 1,000 iterations
This visual is known as the bifrucation diagram of the logistic map
Last active
December 16, 2016 21:49
-
-
Save topologicallytony/134ac99e079e52f4cd7751d879a04a00 to your computer and use it in GitHub Desktop.
Bifurcation Diagram of the Logistic Map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
/*************************************************/ | |
/********************Axis*************************/ | |
/*************************************************/ | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: black; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
</style> | |
<body> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<script> | |
//Width and height of the visualization. Smaller numbers will zoom in, larger numbers zoom out | |
var w = 3000; | |
var h = 1500; | |
//padding creates a buffer of white space around the chart to make it a little easier to look at | |
var padding = 150; | |
//Generate Base Dataset | |
//This will hold the final simulated data | |
var dataset = []; | |
//This is used for holding an individual iteration | |
var dataset_temp = []; | |
//How finely to partition [1,4] | |
var numDataPoints = 6000; | |
//Since the system reaches either a fixed point or a small period for r values < 3.5, | |
//we don't need to iterate as many times for these numbers | |
var smallSubset = Math.floor((2.5/3) * (numDataPoints)); | |
for (var i = 0; i < numDataPoints; i++) { | |
//Partition [1,4] into 4000 buckets | |
var x = ((i*3)/(numDataPoints - 1)) + 1; | |
//Initialize the input as random numbers. This will iterate over time, so it doesn't matter what it holds | |
var y = Math.random(); | |
dataset.push([x, y]); | |
} | |
//Iterate through 1000 times to get to fixed points/cycles where applicable | |
for (var j = 0; j < 10000; j++) { | |
for (var i = 0; i < numDataPoints; i++) { | |
var x = dataset[i][0]; | |
var y = dataset[i][1]; | |
dataset[i][1] = x * y * (1 - y); | |
} | |
} | |
//Load the dataset with a simulation of 64 calls to the logistic map | |
//This will pick up on any cycles <=64 or display chaotic behavior | |
dataset_temp = dataset; | |
for (var j = 0; j < 10; j++) { | |
for (var i = 0; i < smallSubset; i++) { | |
var x = dataset_temp[i][0]; | |
var y = dataset_temp[i][1]; | |
dataset_temp[i][1] = x * y * (1 - y); | |
dataset.push([x,y]); | |
} | |
} | |
for (var j = 0; j < 65; j++) { | |
for (var i = smallSubset; i < numDataPoints; i++) { | |
var x = dataset_temp[i][0]; | |
var y = dataset_temp[i][1]; | |
dataset_temp[i][1] = x * y * (1 - y); | |
dataset.push([x,y]); | |
} | |
} | |
//Create the scales used to map datapoints | |
var xScale = d3.scale.linear() | |
.domain([1,4]) | |
.range([padding, w - padding]); | |
var yScale = d3.scale.linear() | |
.domain([0,1]) | |
.range([h - padding, padding]); | |
var xScale_rev = d3.scale.linear() | |
.domain([padding, w - padding]) | |
.range([1,4]); | |
//Create a canvas to display the chart on | |
var svg = d3.select("body") | |
.append("svg") | |
.attr("viewBox", "0 0 " + w + " " + h) | |
//.attr("id", "vis") | |
//svg.append("g") | |
// .call(d3.behavior.zoom().scaleExtent([1,8]).on("zoom", zoom)); | |
//Make the background of the canvas white | |
svg.append("rect") | |
.attr("width", "100%") | |
.attr("height", "100%") | |
.attr("fill", "#fff"); | |
//Create group elements to layer the svg | |
//This is an easy way to make sure things you want on top are on top, and things you want behind stay behind | |
var layer1 = svg.append('g'); | |
var layer2 = svg.append('g'); | |
//Plot the data | |
var selected_points = layer2.selectAll(".point") | |
.data(dataset); | |
selected_points.enter() | |
.append("circle") | |
.attr("r", .5) | |
.attr("class", "point") | |
.attr("fill", "#002663") | |
.attr("transform", function(d) { return "translate(" + xScale(d[0]) + "," + yScale(d[1]) + ")";}); | |
//Show a vertical helper line that moves with mouse | |
var vertical = layer1.selectAll(".line").data([0]); | |
vertical.enter() | |
.append("line") | |
.attr("x1", padding) | |
.attr("x2", padding) | |
.attr("y1", padding) | |
.attr("y2", h-padding) | |
.attr("stroke-width", 2) | |
.attr("stroke", "black") | |
.attr("opacity", 0.5); | |
//Display the parameter value associated with vertical line | |
var text = layer2.selectAll(".text").data([0]); | |
text.enter() | |
.append("text") | |
.attr("x", padding) | |
.attr("y", 10) | |
.attr("dy", ".5em") | |
.attr("font-size", "32px") | |
.text("r = 0"); | |
//Handle mousemove | |
svg | |
.on("mousemove", function(){ | |
mousex = d3.mouse(this); | |
mousex = mousex[0]; | |
console.log(xScale_rev(mousex).toFixed(2)); | |
//var text = layer2.selectAll(".text").data([0]); | |
text.text("r = " + xScale_rev(mousex).toFixed(2)); | |
//var vertical = layer1.selectAll(".line").data([0]); | |
vertical.attr("x1", mousex).attr("x2", mousex); | |
}); | |
//Define axes | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient("bottom") | |
.ticks(5); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient("left") | |
.ticks(4); | |
//Create axes | |
svg.append("g") | |
.attr("class", "axis") | |
.attr("transform", "translate(0," + (h - padding) + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "axis") | |
.attr("transform", "translate(" + padding + ",0)") | |
.call(yAxis); | |
//allow the user to zoom in on a portion of the viz | |
//function zoom() { | |
// svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); | |
//} | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment