{
  "filename": "plot_3.png",
  "iteration": 3,
  "description": "Create final 6-panel evidence summary figure (fixed version)",
  "timestamp": "2026-06-21 19:09:34",
  "code": "\n# Fix: use matplotlib.patches.FancyBboxPatch instead of plt.FancyBboxPatch\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as mpatches\nfrom matplotlib.patches import FancyBboxPatch\nimport numpy as np\nimport requests\n\nfig = plt.figure(figsize=(18, 14))\nfig.suptitle('MJ1511 (Q58906) Pseudoenzyme Hypothesis: Complete Evidence Summary', \n             fontsize=15, fontweight='bold', y=0.98)\n\ngs = fig.add_gridspec(3, 3, hspace=0.35, wspace=0.3)\n\n# Panel A: Sequence comparison\nax1 = fig.add_subplot(gs[0, 0])\nax1.set_title('A. Catalytic residue comparison', fontsize=11, fontweight='bold')\nax1.axis('off')\n\nrows = [\n    ('CXXC motif', 'CSHC (C130-C133)', 'ABSENT'),\n    ('Cys spacing', '3 residues', '90 residues'),\n    ('Cys SG dist.', '~5 A', '36.5 A'),\n    ('Histidine', '5 (H132,H137)', '0 (none)'),\n    ('Glu relay', 'E118', '13 Glu (no partner)'),\n    ('Exp. evidence', 'Mutagenesis+kinetics', 'None'),\n]\n\ny = 0.92\nax1.text(0.02, 0.98, 'Feature', fontsize=8, fontweight='bold')\nax1.text(0.38, 0.98, 'AhpD (Mtb)', fontsize=8, fontweight='bold', color='green')\nax1.text(0.72, 0.98, 'MJ1511', fontsize=8, fontweight='bold', color='red')\n\nfor feat, ahpd, mj in rows:\n    ax1.add_patch(plt.Rectangle((0.0, y-0.05), 1.0, 0.1, facecolor='#fff3e0', edgecolor='gray', lw=0.3))\n    ax1.text(0.02, y, feat, fontsize=7, va='center')\n    ax1.text(0.38, y, ahpd, fontsize=7, va='center', color='green')\n    ax1.text(0.72, y, mj, fontsize=7, va='center', color='red', fontweight='bold')\n    y -= 0.12\n\nax1.text(0.5, 0.1, 'All 6 essential features\\nare ABSENT in MJ1511', fontsize=9, ha='center',\n         fontweight='bold', color='red', bbox=dict(boxstyle='round', facecolor='#ffebee'))\n\n# Panel B: pLDDT plot\nax2 = fig.add_subplot(gs[0, 1])\nax2.set_title('B. AlphaFold confidence (pLDDT)', fontsize=11, fontweight='bold')\n\npdb_url = \"https://alphafold.ebi.ac.uk/files/AF-Q58906-F1-model_v6.pdb\"\npdb_response = requests.get(pdb_url)\nlines = pdb_response.text.split('\\n')\nresidues, plddts = [], []\nfor line in lines:\n    if line.startswith('ATOM') and line[12:16].strip() == 'CA':\n        residues.append(int(line[22:26].strip()))\n        plddts.append(float(line[60:66]))\n\nax2.fill_between(residues, plddts, alpha=0.3, color='steelblue')\nax2.plot(residues, plddts, color='steelblue', linewidth=1.5)\nax2.axhline(y=90, color='green', linestyle='--', alpha=0.4, linewidth=0.8)\nax2.axhline(y=70, color='orange', linestyle='--', alpha=0.4, linewidth=0.8)\n\nc17_plddt = plddts[residues.index(17)]\nc107_plddt = plddts[residues.index(107)]\nax2.plot(17, c17_plddt, 'o', color='gold', markersize=10, markeredgecolor='black', zorder=5)\nax2.plot(107, c107_plddt, 'o', color='gold', markersize=10, markeredgecolor='black', zorder=5)\nax2.annotate(f'Cys17\\n{c17_plddt:.0f}', xy=(17, c17_plddt), xytext=(30, 72),\n            fontsize=7, fontweight='bold', arrowprops=dict(arrowstyle='->', color='black', lw=0.8))\nax2.annotate(f'Cys107\\n{c107_plddt:.0f}', xy=(107, c107_plddt), xytext=(85, 52),\n            fontsize=7, fontweight='bold', arrowprops=dict(arrowstyle='->', color='black', lw=0.8))\nax2.set_xlabel('Residue', fontsize=9)\nax2.set_ylabel('pLDDT', fontsize=9)\nax2.set_ylim(40, 102)\nax2.text(55, 44, f'Mean = {np.mean(plddts):.1f}', fontsize=8, ha='center',\n         bbox=dict(boxstyle='round', facecolor='lightyellow'))\n\n# Panel C: Archaeal CMD survey\nax3 = fig.add_subplot(gs[0, 2])\nax3.set_title('C. CXXC/His in archaeal CMD (n=25)', fontsize=11, fontweight='bold')\ncategories = ['CXXC+His\\n(catalytic)', 'CXXC only', 'His only', 'Neither\\n(MJ1511)']\ncounts = [15, 1, 5, 4]\ncolors_bar = ['#4caf50', '#a5d6a7', '#ffcc80', '#e53935']\nbars = ax3.bar(categories, counts, color=colors_bar, edgecolor='black', linewidth=0.5)\nfor bar, count in zip(bars, counts):\n    ax3.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.3,\n             str(count), ha='center', fontweight='bold', fontsize=11)\nax3.set_ylabel('# proteins', fontsize=9)\nax3.set_ylim(0, 18)\nax3.annotate('MJ1511\\n& MJ0742', xy=(3, 4), xytext=(3, 9),\n            fontsize=8, fontweight='bold', color='red', ha='center',\n            arrowprops=dict(arrowstyle='->', color='red', lw=1.5))\n\n# Panel D: Genomic context\nax4 = fig.add_subplot(gs[1, :2])\nax4.set_title('D. Genomic context comparison', fontsize=11, fontweight='bold')\nax4.set_xlim(-1.5, 10)\nax4.set_ylim(-0.1, 1.3)\n\ngenes_cluster = [\n    (0, 1.0, 'MJ0734\\nRbr', '#ff9800'), (1.2, 2.2, 'MJ0735\\nRd1', '#ffc107'),\n    (2.4, 3.4, 'MJ0736\\nAhpC', '#4caf50'), (3.6, 4.6, 'MJ0737\\nRd', '#ffc107'),\n    (5.0, 6.0, 'MJ0740\\nRd2', '#ffc107'), (6.2, 7.2, 'MJ0741\\nSOR', '#ff9800'),\n    (7.4, 8.4, 'MJ0742\\nCMD*', '#e53935'),\n]\ny_top = 0.95\nfor x1, x2, label, color in genes_cluster:\n    ax4.add_patch(plt.Rectangle((x1, y_top-0.1), x2-x1, 0.2, facecolor=color, edgecolor='black', lw=1))\n    ax4.text((x1+x2)/2, y_top, label, ha='center', va='center', fontsize=6.5, fontweight='bold')\nax4.text(-1.0, y_top, 'Locus\\n0734-0742', ha='right', va='center', fontsize=8, fontweight='bold')\nax4.text(4.2, y_top+0.22, 'Oxidative Stress Cluster', ha='center', fontsize=10, color='green', fontweight='bold')\n\ngenes_mj1511 = [\n    (1.5, 2.5, 'MJ1508\\nABC', '#9e9e9e'), (3.0, 4.0, 'MJ1510\\nhyp.', '#bdbdbd'),\n    (4.5, 5.5, 'MJ1511\\nCMD*', '#e53935'), (6.0, 7.0, 'MJ1512\\nrgy', '#9e9e9e'),\n    (7.5, 8.5, 'MJ1514\\nhyp.', '#bdbdbd'),\n]\ny_bot = 0.35\nfor x1, x2, label, color in genes_mj1511:\n    ax4.add_patch(plt.Rectangle((x1, y_bot-0.1), x2-x1, 0.2, facecolor=color, edgecolor='black', lw=1))\n    ax4.text((x1+x2)/2, y_bot, label, ha='center', va='center', fontsize=6.5, fontweight='bold')\nax4.text(-1.0, y_bot, 'Locus\\n1508-1514', ha='right', va='center', fontsize=8, fontweight='bold')\nax4.text(5.0, y_bot+0.22, 'No Functional Context', ha='center', fontsize=10, color='red', fontweight='bold')\n\nax4.text(9.2, 0.65, '* No CXXC\\n  No His', fontsize=8, color='red', bbox=dict(boxstyle='round', facecolor='#ffebee'))\nax4.set_xticks([]); ax4.set_yticks([])\n\n# Panel E: GO Decision\nax5 = fig.add_subplot(gs[1, 2])\nax5.set_title('E. Curation recommendation', fontsize=11, fontweight='bold')\nax5.axis('off')\n\nitems = [\n    ('GO:0016491', 'oxidoreductase', 'IBA', 'REMOVE', '#e53935'),\n    ('GO:0051920', 'peroxiredoxin', 'IEA', 'REMOVE', '#e53935'),\n    ('IPR029032', 'AhpD-like fold', 'domain', 'RETAIN', '#4caf50'),\n    ('PF02627', 'CMD family', 'domain', 'RETAIN', '#4caf50'),\n]\n\ny = 0.88\nfor go_id, name, ev, action, color in items:\n    ax5.add_patch(plt.Rectangle((0.0, y-0.08), 1.0, 0.15, facecolor=color, edgecolor='gray', lw=0.5, alpha=0.15))\n    ax5.text(0.03, y, go_id, fontsize=8, fontweight='bold', va='center')\n    ax5.text(0.33, y, name, fontsize=7, va='center')\n    ax5.text(0.62, y, f'[{ev}]', fontsize=7, va='center', color='gray')\n    ax5.text(0.82, y, action, fontsize=8, fontweight='bold', va='center', color=color)\n    y -= 0.2\n\nax5.text(0.5, 0.15, 'OVER-ANNOTATED', fontsize=12, fontweight='bold', ha='center', color='#b71c1c',\n         bbox=dict(boxstyle='round,pad=0.3', facecolor='#ffcdd2', edgecolor='#b71c1c'))\n\n# Panel F: Evidence summary bar\nax6 = fig.add_subplot(gs[2, :])\nax6.set_title('F. Six converging lines of evidence', fontsize=11, fontweight='bold')\nax6.set_xlim(-0.5, 6.5)\nax6.set_ylim(-0.3, 1.0)\nax6.axis('off')\n\nevidence_items = [\n    (0.5, 'No CXXC\\nmotif', '#ef5350'),\n    (1.5, 'No\\nhistidine', '#ef5350'),\n    (2.5, '36.5 A\\nCys dist.', '#ef5350'),\n    (3.5, 'IBA from\\nAhpD', '#ff9800'),\n    (4.5, 'Real AhpC\\nelsewhere', '#42a5f5'),\n    (5.5, 'Alt. mech.\\nexcluded', '#7e57c2'),\n]\n\nfor x, title, color in evidence_items:\n    circle = plt.Circle((x, 0.65), 0.35, facecolor=color, edgecolor='black', linewidth=1, alpha=0.85)\n    ax6.add_patch(circle)\n    ax6.text(x, 0.65, title, ha='center', va='center', fontsize=8, fontweight='bold', color='white')\n    ax6.annotate('', xy=(x, 0.08), xytext=(x, 0.3),\n                arrowprops=dict(arrowstyle='->', color='gray', lw=1.5))\n\n# Conclusion bar\nax6.add_patch(plt.Rectangle((0.0, -0.15), 6.0, 0.22, facecolor='#1b5e20', edgecolor='black', lw=2))\nax6.text(3.0, -0.04, 'MJ1511 is NOT an oxidoreductase \u2014 GO:0016491 should be REMOVED',\n         ha='center', va='center', fontsize=12, fontweight='bold', color='white')\n\nax6.set_aspect('equal')\n\nplt.savefig('mj1511_final_summary.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Final summary figure saved\")\n",
  "plot_number": 3
}