codexaldose-ketose-open-chain-connectivity.py
aldose-ketose-open-chain-connectivity.py
"""Original Fischer comparison; Python 3.14, matplotlib 3.10.7.
Run in the intended output directory. No source artwork is used.
"""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch
CARBONYL = "#aa3b20"
REFERENCE = "#166280"
INK = "#223344"
def text(ax, x, y, s, size=13, color=INK, **kwargs):
return ax.text(x, y, s, ha="center", va="center", fontsize=size,
color=color, **kwargs)
def bond(ax, a, b, color=INK, lw=1.7):
ax.plot([a[0], b[0]], [a[1], b[1]], color=color, lw=lw,
solid_capstyle="round", zorder=1)
def fischer(ax, x, ketose=False):
ys = [6.9 - i * .87 for i in range(6)]
for a, b in zip(ys, ys[1:]):
bond(ax, (x, a - .13), (x, b + .13))
for i, y in enumerate(ys, start=1):
col = CARBONYL if i == (2 if ketose else 1) else REFERENCE if i == 5 else INK
text(ax, x - 1.60, y, f"C{i}", 11, col)
if i == 6 or (ketose and i == 1):
text(ax, x, y, r"CH$_2$OH", 14)
elif (ketose and i == 2) or (not ketose and i == 1):
text(ax, x, y, "C", 14, CARBONYL)
for dy in [-.045, .045]:
bond(ax, (x + .16, y + dy), (x + .77, y + dy), CARBONYL)
text(ax, x + 1, y, "O", 15, CARBONYL)
if not ketose:
bond(ax, (x - .77, y), (x - .16, y), CARBONYL)
text(ax, x - 1, y, "H", 14)
else:
# D-glucose C2..C5: R,L,R,R; D-fructose C3..C5: L,R,R.
oh_right = i != 3
text(ax, x, y, "C", 14, col)
for sign, label in [(-1, "H" if oh_right else "HO"),
(1, "OH" if oh_right else "H")]:
bond(ax, (x + sign * .16, y), (x + sign * .77, y))
text(ax, x + sign * 1.04, y, label, 14, col if i == 5 else INK)
text(ax, x, 7.68, "D-fructose" if ketose else "D-glucose", 19, weight="bold")
text(ax, x, 7.25, "ketose • six carbons" if ketose else "aldose • six carbons", 12)
text(ax, x, 1.89, "C2 carbonyl between C1 and C3" if ketose else "C1 carbonyl at a chain end", 12, CARBONYL)
text(ax, x, 1.47, "3 open-chain stereocenters" if ketose else "4 open-chain stereocenters", 12)
def main():
plt.rcParams.update({"font.family": "DejaVu Sans"})
fig, ax = plt.subplots(figsize=(10, 7.3), dpi=140, facecolor="white")
fig.subplots_adjust(left=.025, right=.975, bottom=.035, top=.96)
ax.set(xlim=(0, 12), ylim=(0, 9))
ax.axis("off")
text(ax, 6, 8.65, "One formula, different carbonyl connectivity", 20, weight="bold")
for x, ketose in [(3, False), (9, True)]:
fischer(ax, x, ketose)
ax.axvline(6, ymin=.18, ymax=.85, color="#d3dde2", lw=1)
ax.add_patch(FancyBboxPatch((.5, .12), 11, .86, boxstyle="round,pad=.12",
facecolor="#edf4f6", edgecolor="none"))
text(ax, 6, .71, r"Both: C$_6$H$_{12}$O$_6$ • C5 OH on the right specifies D here", 12, REFERENCE)
text(ax, 6, .33, "Fischer stereocenters: horizontal bonds toward you; vertical bonds away.", 11)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()