codex/power-set-inclusion-cube.py

power-set-inclusion-cube.py
"""Generate power-set-inclusion-cube.png in cwd.

Tested with Python 3.14.4, numpy 2.3.5, matplotlib 3.10.7.
Every vertex is one subset; an upward edge adds exactly one element.
"""

from itertools import combinations
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt


def main():
    universe=('a','b','c')
    vertices=[frozenset(c) for k in range(4) for c in combinations(universe,k)]
    positions={frozenset():(0,0),frozenset('a'):(-2,1.4),frozenset('b'):(0,1.4),frozenset('c'):(2,1.4),
               frozenset('ab'):(-2,2.8),frozenset('ac'):(0,2.8),frozenset('bc'):(2,2.8),frozenset('abc'):(0,4.2)}
    edges=[(s,t) for s in vertices for t in vertices if s<t and len(t)==len(s)+1]
    assert len(vertices)==8 and len(edges)==12
    fig,ax=plt.subplots(figsize=(7.5,5.4),dpi=120,facecolor="white")
    for s,t in edges:
        ax.plot([positions[s][0],positions[t][0]],[positions[s][1],positions[t][1]],color="#aab9c2",lw=1.4,zorder=0)
    for s,(x,y) in positions.items():
        label=r"$\varnothing$" if not s else r"$\{"+','.join(sorted(s))+r"\}$"
        ax.text(x,y,label,ha="center",va="center",fontsize=15,
                bbox={"boxstyle":"round,pad=.35","facecolor":"#e0eef6","edgecolor":"#608aa4"})
    for k,number in enumerate([1,3,3,1]):
        ax.text(3.25,1.4*k,f"Size {k}: {number} subset"+('s' if number!=1 else ''),ha="left",va="center",fontsize=11)
    ax.set(xlim=(-2.8,5.5),ylim=(-.55,4.9))
    ax.axis("off")
    fig.suptitle(r"The power set of $\{a,b,c\}$ has $2^3=8$ members",fontsize=15)
    fig.text(.5,.035,"Each element is either included or excluded. Every upward edge adds one element.\n"
             "The graph is a cube, drawn by subset size to make inclusion visible.",ha="center",fontsize=10)
    fig.tight_layout(rect=(0,.075,1,.92))
    fig.savefig(Path.cwd()/"power-set-inclusion-cube.png",facecolor="white",transparent=False)
    plt.close(fig)


if __name__ == "__main__":
    main()