codexconditional-probability-dice.py
conditional-probability-dice.py
"""Show exact conditional probabilities on the 36 ordered dice outcomes."""
from fractions import Fraction
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from matplotlib.patches import Patch
import numpy as np
def main():
first, second = np.meshgrid(np.arange(1, 7), np.arange(1, 7))
event_a = first + second >= 9
event_b = first == 6
both = event_a & event_b
assert event_a.sum() == 10 and event_b.sum() == 6 and both.sum() == 4
assert Fraction(int(both.sum()), int(event_b.sum())) == Fraction(2, 3)
assert Fraction(int(both.sum()), int(event_a.sum())) == Fraction(2, 5)
categories = event_a.astype(int) + 2 * event_b.astype(int)
colors = ['#edf1f5', '#f3c277', '#9ac5e5', '#9e86c8']
plt.rcParams.update({'font.size': 12})
fig, axes = plt.subplots(1, 2, figsize=(10.8, 5.8), layout='constrained',
facecolor='white', gridspec_kw={'width_ratios': [1.3, 1]})
ax, summary = axes
ax.imshow(categories, origin='lower', cmap=ListedColormap(colors),
vmin=-.5, vmax=3.5, extent=(.5, 6.5, .5, 6.5))
for x in range(1, 7):
for y in range(1, 7):
ax.text(x, y, f'{x + y}', ha='center', va='center', color='#18212b')
ax.set(xticks=range(1, 7), yticks=range(1, 7), xlabel='First die', ylabel='Second die',
title='36 equally likely ordered outcomes\nNumbers inside cells are the sums')
ax.set_xticks(np.arange(.5, 7), minor=True)
ax.set_yticks(np.arange(.5, 7), minor=True)
ax.grid(which='minor', color='white', linewidth=2)
ax.tick_params(which='minor', length=0)
summary.axis('off')
summary.text(0, .96, 'A: sum is at least 9\nB: first die is 6', va='top', fontsize=14)
summary.legend(handles=[Patch(facecolor=colors[1], label='A only'),
Patch(facecolor=colors[2], label='B only'),
Patch(facecolor=colors[3], label='Both A and B'),
Patch(facecolor=colors[0], label='Neither')],
loc='upper left', bbox_to_anchor=(-.02, .76), frameon=False)
summary.text(0, .40, 'Condition on B: retain 6 cells\n4 satisfy A, so P(A | B) = 2/3',
va='top', fontsize=13)
summary.text(0, .22, 'Condition on A: retain 10 cells\n4 satisfy B, so P(B | A) = 2/5',
va='top', fontsize=13)
summary.text(0, .04, 'Same overlap, different denominators', fontsize=12, color='#4a4a4a')
fig.suptitle('Conditional probability restricts the outcome space', fontsize=16)
fig.savefig(Path.cwd() / 'conditional-probability-dice.png', dpi=120, facecolor='white')
plt.close(fig)
if __name__ == '__main__':
main()