codextotal-probability-partition-population.py
total-probability-partition-population.py
"""Draw an original constructed finite-population total-probability model.
Tested with Python 3.14, matplotlib 3.10.7 and numpy 2.3.5.
Run from _media; the opaque PNG is written to the current directory.
"""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
def main():
plt.rcParams.update({"font.family": "DejaVu Sans", "font.size": 13})
fig, ax = plt.subplots(figsize=(10.4, 6.2), dpi=100)
fig.patch.set_facecolor("white")
ax.set_facecolor("white")
ax.set(xlim=(0, 1), ylim=(0, 1))
ax.axis("off")
ink, blue, orange = "#193047", "#1976a3", "#d97721"
ax.text(0.5, 0.965, "One event, two disjoint parts", ha="center",
va="top", fontsize=21, weight="bold", color=ink)
ax.text(0.5, 0.887, "Constructed population: 1,000 equally likely items",
ha="center", color=ink)
left, bottom, width, height = 0.08, 0.34, 0.84, 0.41
parts = [(0.6, 0.1, blue, "#e8f2f7", r"$B_1$: 600 items", 60),
(0.4, 0.25, orange, "#fcf0e6", r"$B_2$: 400 items", 100)]
x = left
for weight, rate, color, pale, label, marked in parts:
w = width * weight
ax.add_patch(Rectangle((x, bottom), w, height, facecolor=pale,
edgecolor="none"))
ax.add_patch(Rectangle((x, bottom), w, height * rate,
facecolor=color, edgecolor="none"))
ax.text(x + w / 2, 0.793, label, ha="center", color=ink,
fontsize=15, weight="bold")
ax.text(x + w / 2, 0.59, f"Group weight = {weight:g}",
ha="center", color=ink, fontsize=14)
ax.text(x + w / 2, 0.526, f"Marked within group = {rate:g}",
ha="center", color=ink)
ax.annotate(f"{marked} marked items", xy=(x + w / 2, bottom + height * rate / 2),
xytext=(x + w / 2, 0.235), ha="center", color=color,
fontsize=15, weight="bold",
arrowprops={"arrowstyle": "->", "color": color, "lw": 1.7})
x += w
ax.add_patch(Rectangle((left, bottom), width, height, fill=False,
edgecolor=ink, linewidth=1.5))
ax.plot([left + 0.6 * width] * 2, [bottom, bottom + height], color=ink, lw=1.5)
ax.text(0.5, 0.125, r"$P(A)=0.6(0.1)+0.4(0.25)=0.16$",
ha="center", fontsize=19, color=ink)
ax.text(0.5, 0.047, "Shaded area = (60 + 100) / 1,000 = 160 / 1,000",
ha="center", color=ink)
fig.subplots_adjust(left=0.01, right=0.99, bottom=0.025, top=0.985)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"),
facecolor="white", transparent=False, dpi=100)
plt.close(fig)
if __name__ == "__main__":
main()