codexcomplete-graphs-small-orders.py
complete-graphs-small-orders.py
"""Draw complete graphs K1 through K5, with exact edge and degree counts."""
from pathlib import Path
from itertools import combinations
import matplotlib.pyplot as plt
import numpy as np
def positions(n):
if n == 1:
return np.array([[0., 0.]])
if n == 2:
return np.array([[-.75, 0.], [.75, 0.]])
if n == 4:
angles = np.pi / 2 + 2 * np.pi * np.arange(3) / 3
return np.vstack((np.column_stack((np.cos(angles), np.sin(angles))), [0., 0.]))
angles = np.pi / 2 + 2 * np.pi * np.arange(n) / n
return np.column_stack((np.cos(angles), np.sin(angles)))
def main():
fig, axes = plt.subplots(1, 5, figsize=(12.4, 3.8), dpi=100, facecolor="white")
for n, ax in enumerate(axes, 1):
p = positions(n)
for i, j in combinations(range(n), 2):
ax.plot(p[[i, j], 0], p[[i, j], 1], color="#617f96", lw=1.65, zorder=1)
ax.scatter(p[:, 0], p[:, 1], s=190, facecolor="#235e88", edgecolor="white", lw=1, zorder=3)
for i, (x, y) in enumerate(p, 1):
ax.text(x, y, str(i), color="white", ha="center", va="center", fontsize=10, zorder=4)
ax.set_aspect("equal"); ax.set(xlim=(-1.2, 1.2), ylim=(-1.25, 1.25))
ax.axis("off"); ax.set_title(rf"$K_{n}$", fontsize=18)
ax.text(.5, -.08, f"Vertices: {n}\nEdges: {n * (n - 1) // 2}\nEach degree: {n - 1}",
transform=ax.transAxes, ha="center", va="top", fontsize=11)
fig.suptitle("Complete graphs: every pair of distinct vertices has an edge", fontsize=16)
fig.text(.5, .035, "In K5, line crossings without vertex markers are not extra vertices.", ha="center", fontsize=11)
fig.tight_layout(rect=(0, .19, 1, .89), w_pad=1)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()