Published
Edited
Nov 27, 2020
Fork of Polya's Urn
1 star
Insert cell
Insert cell
display = {
var prob1 = pr1.value;
var prob2 = pr2.value;
var prob3 = pr3.value;
function urand() {
if(Math.abs(pr1.value + pr2.value + pr3.value - 1) < 0.00001) {
if(pr1.value == prob1 && pr2.value == prob2 && pr3.value == prob3) {
var v = Math.random();
if (v < prob1) {
anim(1);
}
else if (v >= prob1 && v <= prob1+prob2) {
anim(2);
}
else if(v > prob1 + prob2) {
anim(3);
}
}else {

alpha[0] = 1;
alpha[1] = 1;
alpha[2] = 1;
prob1 = pr1.value;
prob2 = pr2.value;
prob3 = pr3.value;
points.forEach(point => {
point.seval = 2.0;
point.color = colorScale(point.seval);
});
drawInit();
}
}
}
async function flip10() {
for (let i = 0; i < 10; i++) {
urand();
await new Promise(r => setTimeout(r, 1050));
}
}
const container = html`<div id="parent" style="display: flex; align-items: center">
<div id="chart" >${canvas}</div>
<div id="right" style="flex-grow: 1; margin-right: auto">
<div id="sl3">${pr3}</div>
<br/>
<div id="sl2">${pr2}</div>
<br/>
<div id="sl1">${pr1}</div>
<br/>
<button id="b4" style="margin: 4px">Draw Sample</button>
<button id="button2" style="margin: 4px">Draw 10 Samples</button>
</div>
</div>`;
const b4 = container.querySelector('#b4');
const b5 = container.querySelector('#button2');
b4.onclick = urand;
b5.onclick = flip10;

drawInit();
return container
}
Insert cell
canvas = DOM.canvas(width+2*padding,height+2*padding)
Insert cell
pr1 = number({title: "Blue Probability", value: 0.33, min: 0, max: 1})
Insert cell
pr2 = number({title: "Green Probability", value: 0.33, min: 0, max: 1})
Insert cell
pr3 = number({title: "Red Probability", value: 0.34, min: 0, max: 1})
Insert cell
//prob1 = pr1.value//Generators.input(pr1)
Insert cell
//prob2 = pr2.value//Generators.input(pr2)
Insert cell
//prob3 = pr3.value//Generators.input(pr3)
Insert cell
import {button} from "@jashkenas/inputs"
Insert cell
import {number} from "@jashkenas/inputs"
Insert cell
alpha=[1,1,1]
Insert cell
//run this cell to animate
function anim(inc){
switch(inc) {
case 1:
points.forEach(pt => {
pt.teval = pt.seval * ((alpha[0]+alpha[1]+alpha[2])/(alpha[0])) * pt.x;
});
ball[2] = "#0000FF"
alpha[0] = alpha[0] + 1
break;
case 2:
points.forEach(pt => {
pt.teval = pt.seval * ((alpha[0]+alpha[1]+alpha[2])/(alpha[1])) * pt.y;
});
ball[2] = "#00FF00"
alpha[1] = alpha[1] + 1
break;
case 3:
points.forEach(pt => {
pt.teval = pt.seval * ((alpha[0]+alpha[1]+alpha[2])/(alpha[2])) * pt.z;
});
ball[2] = "#FF0000"
alpha[2] = alpha[2] + 1
break;
}
const duration = 1000;
const ease = d3.easeCubic;

ball[1] = -3
var timer = d3.timer((elapsed) => {
const t = Math.min(1, ease(elapsed / duration));
const t2 = Math.min(1, d3.easeCircle(elapsed / duration));

// var maxval = null
// points.forEach(pt => {
// var ceval = pt.seval * (1-t) + pt.teval * t
// if (maxval == null || maxval < ceval) {
// maxval = ceval
// }
// });
points.forEach(point => {
point.color = colorScale(point.seval * (1 - t) + point.teval * t);
});
// if(t< 0.5) {
// ball[0] = 2*t2;
// }
// else if(t>=0.5) {
// ball[0] = 1 - 2*(t2-0.5);
// ball[1] = 1 - 6*(t2-0.5) + 2;
// }

draw();

if (t === 1) {
timer.stop();
points.forEach(pt => {
pt.seval = pt.teval;
});
// ball[0]=-3;
// ball[1]=-3;
draw();
}

});
}
Insert cell
width = 440
Insert cell
height = 346
Insert cell
size = 4
Insert cell
padding = 80
Insert cell
colorScale = function(x) {
var transf = Math.log(x+1);
return d3.scaleSequential(d3.interpolateViridis)(transf/Math.exp(1))
}



//d3.scaleSequential(d3.interpolateViridis).domain([0, 10]);
Insert cell
ball = [0,0,"#000000"]
Insert cell
points = {
var xl = d3.range(0,1.005,.005);
var yl = d3.range(0,1.005,.005);
var zl = d3.range(0,1.005,.005);
var xk = []
var yk = []
var zk = []
var pointlist = []
var i,j,k;
for (i = 0; i < xl.length; i++) {
for (j = 0; j < yl.length; j++) {
for (k = 0; k < zl.length; k++) {
if(Math.abs((xl[i]+yl[j]+zl[k])-1.0) < 0.0001) {
xk.push(xl[i]);
yk.push(yl[j]);
zk.push(zl[k]);
}
}
}
}
const points = d3.range(xk.length).map(ind => ({
id: ind,
x: xk[ind],
y: yk[ind],
z: zk[ind],
cartx: ((xk[ind] - zk[ind])+1.0)*(width/2),
carty: (Math.sqrt(3)-(yk[ind] * Math.sqrt(3)))*(height / Math.sqrt(3)),
color: colorScale(2.0),
seval: 2.0
}));
return points
}
Insert cell
function draw() {
const ctx = canvas.getContext('2d');
ctx.save();

ctx.clearRect(0, 0, width+2*padding, height+2*padding);

for (let i = 0; i < points.length; ++i) {
const point = points[i];
ctx.fillStyle = point.color;
ctx.fillRect(padding+point.cartx, padding+point.carty, size, size);
}
//draw balls in corners
ctx.fillStyle = "#FF0000"
ctx.beginPath();
ctx.arc(padding-20, height+padding+20, 20, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle = "#00FF00"
ctx.beginPath();
ctx.arc(padding+(width/2)+2, padding-25, 20, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle = "#0000FF"
ctx.beginPath();
ctx.arc(padding + width+20, height+padding+20, 20, 0, 2 * Math.PI);
ctx.fill();

ctx.restore();
}
Insert cell
function drawInit() {
const ctx = canvas.getContext('2d');
ctx.save();

ctx.clearRect(0, 0, width+2*padding, height+2*padding);

points.forEach(point => {
point.color = colorScale(point.seval);
});
for (let i = 0; i < points.length; ++i) {
const point = points[i];
ctx.fillStyle = point.color;
ctx.fillRect(padding+point.cartx, padding+point.carty, size, size);
}
//draw balls in corners
ctx.fillStyle = "#FF0000"
ctx.beginPath();
ctx.arc(padding-20, height+padding+20, 20, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle = "#00FF00"
ctx.beginPath();
ctx.arc(padding+(width/2)+2, padding-25, 20, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle = "#0000FF"
ctx.beginPath();
ctx.arc(padding + width+20, height+padding+20, 20, 0, 2 * Math.PI);
ctx.fill();

ctx.restore();
}
Insert cell
d3 = require('d3')
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