{
  "filename": "plot_2.png",
  "iteration": 2,
  "description": "Comprehensive 3-panel figure: AlphaFold pLDDT, catalytic motif comparison with orthologs, and evolutionary summary",
  "timestamp": "2026-07-06 21:35:50",
  "code": "\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as mpatches\nimport numpy as np\nimport requests\n\n# Re-download AlphaFold PDB for pLDDT data\naf_url = \"https://alphafold.ebi.ac.uk/files/AF-Q9C105-F1-model_v6.pdb\"\nresp = requests.get(af_url, timeout=60)\npdb_text = resp.text\n\n# Parse CA atoms for pLDDT\nca_data = []\nfor line in pdb_text.split('\\n'):\n    if line.startswith('ATOM') and line[12:16].strip() == 'CA':\n        resnum = int(line[22:26].strip())\n        bfactor = float(line[60:66].strip())\n        ca_data.append((resnum, bfactor))\n\nresnums = [r for r, _ in ca_data]\nplddts = [p for _, p in ca_data]\n\nfig, axes = plt.subplots(3, 1, figsize=(16, 14), gridspec_kw={'height_ratios': [2, 2.5, 2]})\n\n# ====== Panel A: pLDDT along sequence ======\nax1 = axes[0]\ncolors = []\nfor p in plddts:\n    if p >= 90: colors.append('#1565C0')      # Very high\n    elif p >= 70: colors.append('#42A5F5')     # High\n    elif p >= 50: colors.append('#FFB74D')     # Low\n    else: colors.append('#EF5350')             # Very low\n\nax1.bar(resnums, plddts, color=colors, width=1, edgecolor='none')\nax1.set_ylabel('pLDDT Score', fontsize=11)\nax1.set_xlabel('Residue Position', fontsize=11)\nax1.set_title('A. AlphaFold Confidence (pLDDT) for S. pombe cts2 (Q9C105)', fontsize=13, fontweight='bold', loc='left')\nax1.axhline(y=90, color='gray', linestyle='--', alpha=0.5, linewidth=0.8)\nax1.axhline(y=70, color='gray', linestyle='--', alpha=0.5, linewidth=0.8)\nax1.axhline(y=50, color='gray', linestyle='--', alpha=0.5, linewidth=0.8)\nax1.set_ylim(0, 105)\nax1.set_xlim(0, 1250)\n\n# Annotate regions\nax1.axvspan(26, 325, alpha=0.1, color='blue')\nax1.text(175, 102, 'GH18 Domain\\n(mean pLDDT=92.7)', ha='center', va='top', fontsize=9, color='#1565C0', fontweight='bold')\nax1.text(780, 102, 'Ser/Thr-rich region\\n(mean pLDDT=35.6, disordered)', ha='center', va='top', fontsize=9, color='#EF5350', fontweight='bold')\n\n# Mark catalytic site\nax1.annotate('N166\\n(replaces\\ncat. Glu)', xy=(166, 89), xytext=(166, 50),\n            fontsize=8, ha='center', color='#D32F2F', fontweight='bold',\n            arrowprops=dict(arrowstyle='->', color='#D32F2F', lw=1.5))\n\n# Legend\nfrom matplotlib.lines import Line2D\nlegend_elements = [\n    mpatches.Patch(facecolor='#1565C0', label='Very high (>90)'),\n    mpatches.Patch(facecolor='#42A5F5', label='High (70-90)'),\n    mpatches.Patch(facecolor='#FFB74D', label='Low (50-70)'),\n    mpatches.Patch(facecolor='#EF5350', label='Very low (<50)'),\n]\nax1.legend(handles=legend_elements, loc='upper right', fontsize=8, title='pLDDT', title_fontsize=9)\n\n# ====== Panel B: Ortholog motif comparison ======\nax2 = axes[1]\nax2.set_xlim(-2, 16)\nax2.set_ylim(-1.5, 7)\nax2.set_title('B. Catalytic Motif Comparison: Orthologs & Reference GH18 Chitinases', fontsize=13, fontweight='bold', loc='left')\n\nproteins = [\n    (\"S. cerevisiae Cts1\\n(P29029, active)\", \"D G F D F D I E N N N E\", \n     [0,0,0,0,0,1,0,1,0,0,0,0], True, \"Active chitinase\"),\n    (\"H. sapiens CHIT1\\n(Q13231, active)\", \"D G L D L D W E Y P G S\",\n     [0,0,0,0,0,1,0,1,0,0,0,0], True, \"Active chitinase\"),\n    (\"S. japonicus cts2\\n(B6JW51, intact motif)\", \"D G F D L D I E H G S S\",\n     [0,0,0,0,0,1,0,1,0,0,0,0], True, \"Ortholog: intact DxDxE\"),\n    (\"H. sapiens CHI3L1\\n(P36222, CLP)\", \"D G L D L A W L Y P G R\",\n     [0,0,0,0,0,2,0,2,0,0,0,0], False, \"Known non-catalytic CLP\"),\n    (\"S. pombe cts2\\n(Q9C105, CLP)\", \"D G F D L E V N K G T N\",\n     [0,0,0,0,0,2,0,2,0,0,0,0], False, \"Non-catalytic CLP\"),\n]\n\ny_positions = [5.5, 4.5, 3.0, 1.0, 0.0]\ncolors_map = {0: '#E8E8E8', 1: '#4CAF50', 2: '#F44336'}\n\nfor idx, (name, residues_str, highlights, is_active, desc) in enumerate(proteins):\n    y = y_positions[idx]\n    residues = residues_str.split()\n    \n    ax2.text(-1.8, y, name, ha='right', va='center', fontsize=8.5, \n             fontweight='bold' if not is_active else 'normal',\n             color='#D32F2F' if not is_active else '#1B5E20')\n    \n    for j, (res, hl) in enumerate(zip(residues, highlights)):\n        color = colors_map[hl]\n        rect = mpatches.FancyBboxPatch((j-0.3, y-0.28), 0.6, 0.56,\n                                        boxstyle=\"round,pad=0.04\",\n                                        facecolor=color, edgecolor='black', linewidth=0.8)\n        ax2.add_patch(rect)\n        fontcolor = 'white' if hl > 0 else 'black'\n        ax2.text(j, y, res, ha='center', va='center', fontsize=10, \n                fontweight='bold', color=fontcolor, family='monospace')\n    \n    ax2.text(12.5, y, desc, ha='left', va='center', fontsize=8, \n             fontstyle='italic', color='#555')\n\n# Dividing lines\nax2.axhline(y=2.0, color='gray', linestyle='--', linewidth=0.8, alpha=0.5)\nax2.axhline(y=3.75, color='#1B5E20', linestyle=':', linewidth=0.5, alpha=0.4)\nax2.text(15.5, 4.2, \"ACTIVE\", fontsize=9, ha='right', va='center', color='#1B5E20', fontweight='bold')\nax2.text(15.5, 0.5, \"NON-CATALYTIC\", fontsize=9, ha='right', va='center', color='#D32F2F', fontweight='bold')\n\n# Column headers\nfor j, label in enumerate(['D','G','x','D','x','D*','x','E*','','','','']):\n    ax2.text(j, 6.5, label, ha='center', va='center', fontsize=9, color='gray', family='monospace',\n            fontweight='bold' if '*' in label else 'normal')\nax2.text(5, 7.0, '3rd cat.\\nAsp', ha='center', va='bottom', fontsize=7, color='#B71C1C')\nax2.text(7, 7.0, 'Cat. Glu\\n(proton\\ndonor)', ha='center', va='bottom', fontsize=7, color='#B71C1C')\n\nax2.axis('off')\n\n# ====== Panel C: Evolutionary summary ======\nax3 = axes[2]\nax3.set_xlim(0, 10)\nax3.set_ylim(0, 5)\nax3.set_title('C. Evolutionary Summary: Lineage-Specific Loss of Chitinase Activity', fontsize=13, fontweight='bold', loc='left')\n\n# Simple phylogenetic tree\n# Ancestor -> S. japonicus (retains DxDxE + chitin)\n# Ancestor -> S. pombe (loses DxDxE + loses chitin)\nax3.plot([2, 4], [2.5, 4], 'k-', linewidth=2)  # to S. japonicus\nax3.plot([2, 4], [2.5, 1], 'k-', linewidth=2)  # to S. pombe\n\n# Ancestor node\nax3.plot(2, 2.5, 'ko', markersize=10, zorder=5)\nax3.text(1.8, 2.5, 'Ancestor\\n(DxDxE intact)', ha='right', va='center', fontsize=9, fontweight='bold')\n\n# S. japonicus\nrect_sj = mpatches.FancyBboxPatch((4.2, 3.4), 5.3, 1.2, boxstyle=\"round,pad=0.15\",\n                                   facecolor='#E8F5E9', edgecolor='#1B5E20', linewidth=1.5)\nax3.add_patch(rect_sj)\nax3.text(6.8, 4.3, 'S. japonicus cts2 (B6JW51)', fontsize=10, fontweight='bold', color='#1B5E20', ha='center')\nax3.text(6.8, 3.7, 'DxDxE intact | Chitin in cell wall | Active chitinase?', fontsize=8, color='#2E7D32', ha='center')\n\n# S. pombe\nrect_sp = mpatches.FancyBboxPatch((4.2, 0.4), 5.3, 1.2, boxstyle=\"round,pad=0.15\",\n                                   facecolor='#FFEBEE', edgecolor='#D32F2F', linewidth=1.5)\nax3.add_patch(rect_sp)\nax3.text(6.8, 1.3, 'S. pombe cts2 (Q9C105)', fontsize=10, fontweight='bold', color='#D32F2F', ha='center')\nax3.text(6.8, 0.7, 'D\u2192E, E\u2192N | No chitin in wall | Non-catalytic CLP', fontsize=8, color='#C62828', ha='center')\n\n# Mutation annotation on branch\nax3.annotate('D\u2192E, E\u2192N\\nmutations', xy=(3.2, 1.6), fontsize=8, ha='center',\n            color='#D32F2F', fontweight='bold', fontstyle='italic',\n            bbox=dict(boxstyle='round,pad=0.3', facecolor='#FFCDD2', edgecolor='#D32F2F', alpha=0.8))\n\nax3.axis('off')\n\nplt.tight_layout()\nplt.savefig('cts2_comprehensive_analysis.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Figure saved: cts2_comprehensive_analysis.png\")\n",
  "plot_number": 2
}