This line graph shows the results of a running a simulation numerous times on the probability of winning (or losing) the Monty Hall door switch game. The blue line represents the probablity of winning the game if the contestant switches doors after being shown the "booby prize" door. The orange line shows the probability of losing if the contestant switches doors.
The game is based on classic Bayesian statistics. I wrote a Python script to run the simulation 1,000 times and output the probabilities of winning and losing over each simulation.
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bayesian Statistics</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lora">
<style>
body {
font-family: 'Lora', serif;
}
path.line {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
path.area {
fill: #e7e7e7;
}
.axis {
shape-rendering: crispEdges;
}
.x.axis line {
stroke: #fff;
}
.x.axis .minor {
stroke-opacity: .5;
}
.x.axis path {
display: none;
}
.y.axis line,
.y.axis path {
fill: none;
stroke: #000;
}
.guideline {
margin-right: 100px;
float: right;
}
</style>
<!-- D3 -->
<script charset="utf-8" src="https://d3js.org/d3.v3.min.js" type="text/javascript"></script>
<!-- D3 Queue -->
<script charset="utf-8" src="https://d3js.org/d3-queue.v3.min.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-12">
<div id="title" class="page-header">
<h2>Bayesian Statistics <small>Simulating the Monty Hall Problem with Python</small></h2>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-12">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="" id="show_guideline">
Show Guideline & Curtain
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-12">
<svg></svg>
</div>
</div>
</div>
<script defer type="text/javascript">
"use strict";
var margin = {
top: 80,
right: 80,
bottom: 80,
left: 80
},
width = 1200 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// Scales and axes. Note the inverted domain for the y-scale: bigger is up!
var x = d3.scale.linear().range([0, width]),
y = d3.scale.linear().range([height, 0]),
xAxis = d3.svg.axis().scale(x).tickSize(-height).tickSubdivide(true),
yAxis = d3.svg.axis().scale(y).ticks(4).orient("right");
// An area generator, for the light fill.
var area = d3.svg.area()
.interpolate("monotone")
.x(function(d) {
return x(d.id);
})
.y0(height)
.y1(function(d) {
return y(d.value);
});
// A line generator, for the dark stroke.
var line = d3.svg.line()
.interpolate("monotone")
.x(function(d) {
return x(d.id);
})
.y(function(d) {
return y(d.value);
});
// get the data
function getData() {
var endpointUrl = 'https://gist.githubusercontent.com/tonmcg/d83cb1dee8602e8292a73f40fa01471c/raw/c3bd8a8c333a1cea787337085bb78f01f782eca9/simulations.csv';
// using d3 Queue to simplify the use of deferreds while awaiting data to load from external sources
d3.queue()
.defer(d3.csv, endpointUrl)
.await(createViz);
}
// create visualization
function createViz(error,data) {
var switchValues = data.map(function(g) {
return {
id: +g[''],
name: 'switch',
value: +g['switch doors']
};
});
var stayValues = data.map(function(g) {
return {
id: +g[''],
name: 'stay',
value: +g['do not switch doors']
};
});
var values = d3.merge([switchValues, stayValues]);
// Compute the minimum and maximum date, and the maximum price.
x.domain(d3.extent(values, function(d) {
return d.id;
}));
y.domain(d3.extent(values, function(d) {
return d.value;
})).nice();
// Add an SVG element with the desired dimensions and margin.
var svg = d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
// Add the clip path.
svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the y-axis.
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ",0)")
.call(yAxis);
var colors = d3.scale.category10();
svg.selectAll('.line')
.data([switchValues,stayValues])
.enter()
.append('path')
.attr('class', 'line')
.style('stroke', function(d) {
return colors(Math.random() * 50);
})
.attr('clip-path', 'url(#clip)')
.attr('d', function(d) {
return line(d);
});
/* Add 'curtain' rectangle to hide entire graph */
var curtain = svg.append('rect')
.attr('x', -1 * width)
.attr('y', -1 * height)
.attr('height', height)
.attr('width', width)
.attr('class', 'curtain')
.attr('transform', 'rotate(180)')
.style('fill', '#ffffff');
/* Optionally add a guideline */
var guideline = svg.append('line')
.attr('stroke', '#333')
.attr('stroke-width', 0)
.attr('class', 'guide')
.attr('x1', 1)
.attr('y1', 1)
.attr('x2', 1)
.attr('y2', height);
/* Create a shared transition for anything we're animating */
var t = svg.transition()
.delay(750)
.duration(6000)
.ease('linear')
.each('end', function() {
d3.select('line.guide')
.transition()
.style('opacity', 0)
.remove();
});
t.select('rect.curtain')
.attr('width', 0);
t.select('line.guide')
.attr('transform', 'translate(' + width + ', 0)');
d3.select("#show_guideline").on("change", function(e) {
guideline.attr('stroke-width', this.checked ? 1 : 0);
curtain.attr("opacity", this.checked ? 0.75 : 1);
});
}
getData();
</script>
</body>
</html>
https://d3js.org/d3.v3.min.js
https://d3js.org/d3-queue.v3.min.js