codexigg-domain-and-disulfide-connectivity.py
igg-domain-and-disulfide-connectivity.py
"""Draw an original IgG connectivity schematic; tested with Python 3.14.
Requires the repository's matplotlib 3.10.7. Run from _media; writes PNG to CWD.
"""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch, Ellipse
HEAVY = '#2466a6'
LIGHT = '#c96520'
BOND = '#a57400'
INK = '#253446'
def main():
plt.rcParams.update({'font.family': 'DejaVu Sans', 'font.size': 12})
fig, ax = plt.subplots(figsize=(10, 6.7), dpi=110, facecolor='white')
fig.subplots_adjust(left=.035, right=.97, bottom=.07, top=.89)
ax.set(xlim=(0, 10), ylim=(-.4, 6.4))
ax.axis('off')
fig.suptitle('IgG: four chains, two binding sites', fontsize=19, color=INK, y=.97)
ax.text(5, 6.12, 'Unrolled connectivity schematic • positions are not atomic coordinates',
ha='center', fontsize=11, color=INK)
def domain(x, y, label, color):
ax.add_patch(FancyBboxPatch((x-.4, y-.34), .8, .68,
boxstyle='round,pad=.04,rounding_size=.15',
facecolor='white', edgecolor=color, linewidth=2.4, zorder=3))
ax.text(x, y, label, ha='center', va='center', color=color, fontsize=14, zorder=4)
for x, name in [(3.5, 'H₁'), (6.5, 'H₂')]:
ax.plot([x, x], [5.47, .45], color=HEAVY, linewidth=4, solid_capstyle='round')
for y, label in [(5.05, r'$V_H$'), (3.9, r'$C_{H1}$'),
(1.8, r'$C_{H2}$'), (.8, r'$C_{H3}$')]:
domain(x, y, label, HEAVY)
ax.text(x, 5.62, 'N', ha='center', color=HEAVY, fontweight='bold')
ax.text(x, .18, 'C', ha='center', color=HEAVY, fontweight='bold')
ax.text(x, -.19, name+' heavy chain', ha='center', color=HEAVY, fontsize=11)
for x, name in [(2, 'L₁'), (8, 'L₂')]:
ax.plot([x, x], [5.47, 3.45], color=LIGHT, linewidth=4, solid_capstyle='round')
domain(x, 5.05, r'$V_L$', LIGHT)
domain(x, 3.9, r'$C_L$', LIGHT)
ax.text(x, 5.62, 'N', ha='center', color=LIGHT, fontweight='bold')
ax.text(x, 3.13, 'C', ha='center', color=LIGHT, fontweight='bold')
ax.text(x, 2.73, name+' light chain', ha='center', color=LIGHT, fontsize=11)
for a, b in [(2, 3.5), (6.5, 8)]:
ax.plot([a, b], [3.5, 3.5], color=BOND, linewidth=3, zorder=5)
ax.text((a+b)/2, 3.28, 'S—S', ha='center', color=BOND, fontsize=11)
ax.plot([3.5, 6.5], [2.72, 2.72], color=BOND, linewidth=3, zorder=5)
ax.text(5, 2.82, 'S—S', ha='center', color=BOND)
ax.text(5, 2.28, 'hinge: heavy–heavy crosslinks', ha='center', fontsize=10, color=INK)
for x in [2.75, 7.25]:
ax.add_patch(Ellipse((x, 5.05), 2.6, 1.0, fill=False,
edgecolor=INK, linestyle='--', linewidth=1.2, zorder=2))
ax.text(.15, 5.03, 'one\nsite', ha='center', va='center', color=INK, fontsize=11)
ax.text(9.6, 5.03, 'one\nsite', ha='center', va='center', color=INK, fontsize=11)
ax.text(5, 4.65, 'paired variable\ndomains', ha='center', va='center', color=INK, fontsize=11)
ax.text(5, 1.29, 'Fc\nportions', ha='center', va='center', color=INK, fontsize=11)
fig.text(.5, .025, 'Colored paths: peptide backbones | Gold: interchain disulfides (multiplicity schematic)\n'
'N and C: chain termini • Intrachain disulfides omitted',
ha='center', fontsize=10, color=INK)
fig.savefig(Path.cwd() / (Path(__file__).stem + '.png'), facecolor='white', transparent=False)
plt.close(fig)
if __name__ == '__main__':
main()