codexglucose-derivative-functional-groups.py
glucose-derivative-functional-groups.py
"""Original Fischer comparison; tested with Python 3.14.4 / Matplotlib 3.10.7.
Run from the intended output directory, as for the repository's other figures.
The open-chain structures are reference forms, not abundance predictions.
"""
from pathlib import Path
import matplotlib.pyplot as plt
INK = "#243746"
ACCENT = "#a34228"
BLUE = "#1a6687"
COMPOUNDS = [
("D-glucose", "CH$_2$OH", "OH", r"C$_6$H$_{12}$O$_6$", "Reference"),
("D-glucuronic acid", "COOH", "OH", r"C$_6$H$_{10}$O$_7$", "C6: alcohol to carboxylic acid"),
("D-glucosamine", "CH$_2$OH", "NH$_2$", r"C$_6$H$_{13}$NO$_5$", "C2: OH replaced by NH2"),
("N-acetyl-D-glucosamine", "CH$_2$OH", "NHAc", r"C$_8$H$_{15}$NO$_6$", "Nitrogen carries an acetyl group"),
]
def label(ax, x, y, text, size=13, color=INK, **kwargs):
ax.text(x, y, text, fontsize=size, ha="center", va="center",
color=color, **kwargs)
def draw(ax, x, compound):
name, tail, amino, formula, change = compound
label(ax, x, 8.0, name, 14, weight="bold")
ys = [7.1 - i * .84 for i in range(6)]
for y1, y2 in zip(ys, ys[1:]):
ax.plot([x, x], [y1-.15, y2+.15], color=INK, lw=1.5)
for carbon, y in enumerate(ys, 1):
color = ACCENT if (carbon == 6 and tail == "COOH") or (carbon == 2 and amino != "OH") else INK
label(ax, x-1.55, y, f"C{carbon}", 10, color)
if carbon in (1, 6):
label(ax, x, y, "CHO" if carbon == 1 else tail, 14, color)
continue
label(ax, x, y, "C", 13, color)
right = carbon != 3
groups = ("H", amino if carbon == 2 else "OH") if right else ("HO", "H")
for direction, group in zip((-1, 1), groups):
ax.plot([x+direction*.15, x+direction*.72], [y, y], color=color, lw=1.5)
label(ax, x+direction*1.02, y, group, 13, color)
label(ax, x, 2.12, formula, 15, BLUE)
label(ax, x, 1.63, change, 10, ACCENT if amino != "OH" or tail == "COOH" else INK)
def main():
plt.rcParams.update({"font.family": "DejaVu Sans"})
fig, ax = plt.subplots(figsize=(13.8, 7.3), dpi=125, facecolor="white")
fig.subplots_adjust(left=.02, right=.98, bottom=.03, top=.97)
ax.set(xlim=(0, 16), ylim=(0, 9.2))
ax.axis("off")
label(ax, 8, 8.83, "Different modifications of a glucose reference skeleton", 20, weight="bold")
for x, compound in zip((2, 6, 10, 14), COMPOUNDS):
draw(ax, x, compound)
for x in (4, 8, 12):
ax.plot([x, x], [1.4, 8.25], color="#d9e1e6", lw=.8)
label(ax, 8, .85, "Ac = acetyl, COCH3. These are neutral, open-chain reference structures.", 12)
label(ax, 8, .38, "Fischer stereocenters: horizontal bonds toward the viewer; vertical bonds away. Cyclic forms are not shown.", 11)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()