{
  "filename": "plot_4.png",
  "iteration": 2,
  "description": "Visualize active-site residue alignment and key divergences between LPL1 (phospholipase B) and ROG1 (MAG lipase)",
  "timestamp": "2026-07-05 07:45:36",
  "code": "\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Create detailed active-site residue comparison\nfig, axes = plt.subplots(1, 2, figsize=(16, 8))\nfig.suptitle('Active-Site Environment Comparison (8\u00c5 from Catalytic Ser)', \n             fontsize=14, fontweight='bold')\n\n# Panel A: Residue-by-residue alignment of active-site environment\nax1 = axes[0]\nax1.axis('off')\nax1.set_title('A. Active-Site Residue Alignment', fontweight='bold')\n\n# Manually aligned active-site residues based on structural/sequence correspondence\n# Format: (Ca_LPL1 res#, Ca_LPL1 aa, Sc_LPL1 res#, Sc_LPL1 aa, ROG1 res#, ROG1 aa, role)\naligned_residues = [\n    (23, 'I', 11, 'I', None, '-', 'hydrophobic core'),\n    (24, 'H', 12, 'H', 195, 'H', 'oxyanion hole (HG)'),\n    (25, 'G', 13, 'G', 196, 'G', 'oxyanion hole (HG)'),\n    (26, 'L', 14, 'L', 197, 'L', 'hydrophobic core'),\n    (102, 'G', 88, 'G', 267, 'G', 'GXSXG motif pos1'),\n    (103, 'Y', 89, 'Y', 268, 'H', 'GXSXG motif pos2 \u2605'),\n    (104, 'S', 90, 'S', 269, 'S', 'CATALYTIC SER'),\n    (105, 'L', 91, 'Q', 270, 'L', 'GXSXG motif pos4'),\n    (106, 'G', 92, 'G', 271, 'G', 'GXSXG motif pos5'),\n    (107, 'G', 93, 'G', 272, 'G', 'after motif'),\n    (108, 'L', 94, 'L', 273, 'L', 'after motif'),\n    (133, 'T', 121, 'T', 300, 'T', 'downstream loop'),\n    (134, 'F', 122, 'M', 301, 'L', 'substrate pocket'),\n    (135, 'A', 123, 'A', 302, 'A', 'conserved'),\n    (136, 'T', 124, 'T', 303, 'S', 'conservative'),\n    (137, 'P', 125, 'P', 304, 'P', 'conserved'),\n    (138, 'H', 126, 'H', 305, 'L', 'DIVERGENT \u2605\u2605'),\n    (206, 'D', 199, 'D', 372, 'D', 'CATALYTIC ASP'),\n    (504, 'H', 414, 'H', 552, 'H', 'CATALYTIC HIS'),\n]\n\n# Draw as a table\ny_pos = 0.95\nheader = f\"{'Ca_LPL1':>12}  {'Sc_LPL1':>12}  {'Sc_ROG1':>12}  {'Role':<25}\"\nax1.text(0.02, y_pos, header, fontfamily='monospace', fontsize=8, fontweight='bold',\n         transform=ax1.transAxes)\ny_pos -= 0.03\nax1.text(0.02, y_pos, '-' * 70, fontfamily='monospace', fontsize=7, \n         transform=ax1.transAxes)\ny_pos -= 0.03\n\nfor ca_num, ca_aa, sc_num, sc_aa, rog_num, rog_aa, role in aligned_residues:\n    # Color-code differences\n    rog_str = f\"{rog_aa}{rog_num}\" if rog_num else f\"{rog_aa:>4}\"\n    ca_sc_match = ca_aa == sc_aa\n    ca_rog_match = ca_aa == rog_aa\n    \n    # Highlight divergent positions\n    if '\u2605' in role:\n        color = 'red'\n        weight = 'bold'\n    elif 'CATALYTIC' in role:\n        color = 'darkgreen'\n        weight = 'bold'\n    elif ca_sc_match and not ca_rog_match:\n        color = 'blue'  # LPL1 shared, ROG1 different\n        weight = 'normal'\n    else:\n        color = 'black'\n        weight = 'normal'\n    \n    line = f\"  {ca_aa}{ca_num:>4}       {sc_aa}{sc_num:>4}      \"\n    if rog_num:\n        line += f\" {rog_aa}{rog_num:>4}     \"\n    else:\n        line += f\"  {rog_aa:>4}     \"\n    line += f\" {role}\"\n    \n    ax1.text(0.02, y_pos, line, fontfamily='monospace', fontsize=7.5,\n             color=color, fontweight=weight, transform=ax1.transAxes)\n    y_pos -= 0.035\n\n# Legend\ny_pos -= 0.03\nax1.text(0.02, y_pos, 'Colors:', fontfamily='monospace', fontsize=7, fontweight='bold',\n         transform=ax1.transAxes)\ny_pos -= 0.025\nax1.text(0.02, y_pos, '  Green = catalytic triad', fontfamily='monospace', fontsize=7,\n         color='darkgreen', transform=ax1.transAxes)\ny_pos -= 0.025\nax1.text(0.02, y_pos, '  Red = key divergent positions (\u2605)', fontfamily='monospace', fontsize=7,\n         color='red', transform=ax1.transAxes)\ny_pos -= 0.025\nax1.text(0.02, y_pos, '  Blue = LPL1 shared, ROG1 different', fontfamily='monospace', fontsize=7,\n         color='blue', transform=ax1.transAxes)\n\n# Panel B: Key differences visualization\nax2 = axes[1]\nax2.set_title('B. Key Active-Site Divergences', fontweight='bold')\n\n# Bar chart showing key positions\npositions = ['GxSxG\\npos2', 'Loop\\npos134/122', 'Critical\\npos138/126']\nca_vals = [1, 1, 1]  # Y, F, H\nsc_vals = [1, 0.7, 1]  # Y, M, H\nrog_vals = [0, 0.3, 0]  # H, L, L\n\nx = np.arange(len(positions))\nwidth = 0.25\n\n# Use text annotations instead of bars\nax2.set_xlim(-0.5, 2.5)\nax2.set_ylim(0, 4)\nax2.set_xticks(x)\nax2.set_xticklabels(positions)\nax2.set_yticks([])\n\n# Draw residue boxes\nfor i, pos_label in enumerate(positions):\n    # Ca_LPL1\n    aa_ca = ['Y103', 'F134', 'H138'][i]\n    ax2.add_patch(plt.Rectangle((i-0.35, 2.8), 0.22, 0.8, facecolor='#6699ff', edgecolor='black'))\n    ax2.text(i-0.24, 3.2, aa_ca, ha='center', va='center', fontsize=9, fontweight='bold')\n    \n    # Sc_LPL1\n    aa_sc = ['Y89', 'M122', 'H126'][i]\n    ax2.add_patch(plt.Rectangle((i-0.11, 2.8), 0.22, 0.8, facecolor='#66cc66', edgecolor='black'))\n    ax2.text(i, 3.2, aa_sc, ha='center', va='center', fontsize=9, fontweight='bold')\n    \n    # Sc_ROG1\n    aa_rog = ['H268', 'L301', 'L305'][i]\n    color = '#ff6666' if aa_rog[0] != aa_ca[0] else '#ff9999'\n    ax2.add_patch(plt.Rectangle((i+0.13, 2.8), 0.22, 0.8, facecolor=color, edgecolor='black'))\n    ax2.text(i+0.24, 3.2, aa_rog, ha='center', va='center', fontsize=9, fontweight='bold')\n\n# Labels\nax2.text(-0.24, 3.8, 'Ca_LPL1', ha='center', fontsize=8, color='#336699', fontweight='bold')\nax2.text(0, 3.8, 'Sc_LPL1', ha='center', fontsize=8, color='#339933', fontweight='bold')\nax2.text(0.24, 3.8, 'Sc_ROG1', ha='center', fontsize=8, color='#cc3333', fontweight='bold')\n\n# Annotations\nax2.text(0, 2.3, 'GXSXG motif: Y (aromatic) in LPL1\\nvs H (basic) in ROG1', \n         ha='center', fontsize=8, fontstyle='italic')\nax2.text(1, 1.7, 'Substrate pocket: F/M (bulky) in LPL1\\nvs L (small) in ROG1', \n         ha='center', fontsize=8, fontstyle='italic')\nax2.text(2, 1.1, 'Key position: H (His) in BOTH LPL1s\\nvs L (Leu) in ROG1 \u2014 strongly\\nsuggests functional divergence', \n         ha='center', fontsize=8, fontstyle='italic', color='red')\n\n# Summary box\nax2.text(1, 0.3, \n         'CONCLUSION: LPL1 active sites share 3 key\\nresidues that DIFFER from ROG1, consistent\\nwith different substrate specificity',\n         ha='center', fontsize=9, fontweight='bold',\n         bbox=dict(boxstyle='round', facecolor='lightyellow', edgecolor='orange', lw=2))\n\nplt.tight_layout()\nplt.savefig('active_site_comparison.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Active site comparison figure saved\")\n",
  "plot_number": 4
}