{
  "filename": "plot_1.png",
  "iteration": 1,
  "description": "Creating evidence matrix and catalytic triad comparison visualization for Epe1 demethylase hypothesis",
  "timestamp": "2026-07-05 12:55:49",
  "code": "\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as mpatches\nimport numpy as np\n\nfig, axes = plt.subplots(2, 1, figsize=(14, 14), gridspec_kw={'height_ratios': [1.2, 1]})\n\n# === Panel A: Evidence Matrix ===\nax = axes[0]\nax.set_title('Evidence Matrix: Epe1 Histone Demethylase Activity (GO:0032452)', fontsize=14, fontweight='bold', pad=15)\n\n# Define evidence items\nevidence = [\n    {'citation': 'Isaac et al. 2007\\nPMID:17449867', 'type': 'Direct assay', 'verdict': 'Refutes',\n     'finding': 'No detectable demethylase\\nactivity; non-conserved\\nFe(II) residues'},\n    {'citation': 'Raiymbek et al. 2020\\nPMID:32195666', 'type': 'Mutant/\\nbiochemistry', 'verdict': 'Refutes',\n     'finding': 'Non-enzymatic function;\\nJmjC mutations disrupt\\nSwi6 interaction'},\n    {'citation': 'Trewick et al. 2007\\nPMID:17948055', 'type': 'Mutant\\nphenotype', 'verdict': 'Qualifies',\n     'finding': 'JmjC domain required but\\nmay be protein hydroxylase\\nnot demethylase'},\n    {'citation': 'Horton et al. 2011\\nPMID:21167174', 'type': 'Structural/\\nbiochemical', 'verdict': 'Refutes',\n     'finding': 'PHF2 with same Tyr\u2192His\\nsubstitution is catalytically\\ndead'},\n    {'citation': 'Trewick et al. 2005\\nPMID:15809658', 'type': 'Computational/\\nreview', 'verdict': 'Qualifies',\n     'finding': 'Proposed as putative\\ndemethylase OR protein\\nhydroxylase'},\n    {'citation': 'Sorida et al. 2019\\nPMID:31206516', 'type': 'In vivo\\nChIP', 'verdict': 'Supports\\n(indirect)',\n     'finding': 'JmjC-mediated H3K9me\\ndemethylation in vivo\\n(could be non-enzymatic)'},\n    {'citation': 'Audergon et al. 2015\\nPMID:25838386', 'type': 'Genetic/\\nepigenetic', 'verdict': 'Supports\\n(indirect)',\n     'finding': 'epe1 loss allows H3K9me\\nmaintenance (genetic,\\nnot direct assay)'},\n    {'citation': 'Yaseen et al. 2022\\nPMID:35879419', 'type': 'Genetic/\\nfunctional', 'verdict': 'Qualifies',\n     'finding': 'tEpe1 requires functional\\nJmjC domain for resistance\\n(domain required)'},\n    {'citation': 'Sweta & Sharma 2021\\nPMID:33533152', 'type': 'Functional/\\ngenetic', 'verdict': 'Refutes',\n     'finding': 'C-terminal (403-948) key;\\nH3K9ac & PolII recruitment\\nnot demethylation'},\n    {'citation': 'Sequence analysis\\n(this study)', 'type': 'Computational', 'verdict': 'Refutes',\n     'finding': 'His\u2192Tyr at Fe(II) ligand\\nposition 370; incomplete\\ncatalytic triad'},\n    {'citation': 'PomBase\\nGO:0141052', 'type': 'Database\\nannotation', 'verdict': 'Refutes',\n     'finding': 'NOT|enables H3\\ndemethylase activity\\n(IDA, PMID:16362057)'},\n]\n\n# Color map for verdict\nverdict_colors = {\n    'Refutes': '#FF6B6B',\n    'Qualifies': '#FFD93D',\n    'Supports\\n(indirect)': '#95E1D3',\n}\n\ncolumns = ['Citation', 'Evidence Type', 'Verdict', 'Key Finding']\ncol_widths = [0.18, 0.12, 0.10, 0.25]\n\n# Draw table\nn_rows = len(evidence)\nrow_height = 0.065\nstart_y = 0.92\n\n# Header\nfor j, col in enumerate(columns):\n    x = sum(col_widths[:j]) + 0.08\n    ax.text(x + col_widths[j]/2, start_y + 0.02, col, ha='center', va='center',\n            fontweight='bold', fontsize=9, transform=ax.transAxes)\n\n# Data rows\nfor i, ev in enumerate(evidence):\n    y = start_y - (i + 1) * row_height\n    values = [ev['citation'], ev['type'], ev['verdict'], ev['finding']]\n    \n    # Background color based on verdict\n    color = verdict_colors.get(ev['verdict'], '#E8E8E8')\n    rect = mpatches.FancyBboxPatch(\n        (0.06, y - row_height/2 + 0.01), 0.88, row_height - 0.005,\n        boxstyle=\"round,pad=0.002\", facecolor=color, alpha=0.3,\n        transform=ax.transAxes)\n    ax.add_patch(rect)\n    \n    for j, val in enumerate(values):\n        x = sum(col_widths[:j]) + 0.08\n        fontsize = 7 if j == 0 else 7\n        ax.text(x + col_widths[j]/2, y, val, ha='center', va='center',\n                fontsize=fontsize, transform=ax.transAxes)\n\nax.axis('off')\n\n# Legend\nlegend_patches = [\n    mpatches.Patch(color='#FF6B6B', alpha=0.4, label='Refutes demethylase activity'),\n    mpatches.Patch(color='#FFD93D', alpha=0.4, label='Qualifies (JmjC needed but maybe not as demethylase)'),\n    mpatches.Patch(color='#95E1D3', alpha=0.4, label='Supports (indirect in vivo effects only)'),\n]\nax.legend(handles=legend_patches, loc='lower center', ncol=3, fontsize=8, \n          framealpha=0.8, bbox_to_anchor=(0.5, -0.02))\n\n# === Panel B: Catalytic triad comparison ===\nax2 = axes[1]\nax2.set_title('Fe(II) Catalytic Triad Comparison: Active vs Epe1', fontsize=14, fontweight='bold', pad=15)\n\nproteins = ['KDM2A\\n(Human)', 'Jhd1\\n(S. cerevisiae)', 'Epe1\\n(S. pombe)']\nligands = ['Ligand 1\\n(His)', 'Ligand 2\\n(Asp/Glu)', 'Ligand 3\\n(His)']\nresidues = [\n    ['H212', 'D214', 'H284'],  # KDM2A\n    ['H305', 'D307', 'H377'],  # Jhd1\n    ['H297', 'E299', 'Y370'],  # Epe1\n]\nactive = [\n    [True, True, True],\n    [True, True, True],\n    [True, False, False],  # E is tolerable but Y is not\n]\n# Better: for Epe1: H is OK, E may be tolerated, Y is broken\ncanonical = [\n    [True, True, True],\n    [True, True, True],\n    [True, True, False],  # H is conserved, E vs D is conservative, Y for H is broken\n]\n\nbar_width = 0.2\nx = np.arange(len(ligands))\n\nfor i, (prot, res_list, canon_list) in enumerate(zip(proteins, residues, canonical)):\n    colors = ['#4CAF50' if c else '#F44336' for c in canon_list]\n    bars = ax2.bar(x + i * bar_width, [1]*3, bar_width, label=prot, color=colors, \n                   edgecolor='black', linewidth=0.5, alpha=0.8)\n    for j, (bar, res) in enumerate(zip(bars, res_list)):\n        ax2.text(bar.get_x() + bar.get_width()/2., 0.5, res,\n                ha='center', va='center', fontweight='bold', fontsize=11, color='white')\n\nax2.set_xticks(x + bar_width)\nax2.set_xticklabels(ligands, fontsize=11)\nax2.set_yticks([])\nax2.set_ylim(0, 1.5)\nax2.set_xlim(-0.3, 3.1)\n\n# Custom legend\nlegend_elements = [\n    mpatches.Patch(facecolor='#4CAF50', edgecolor='black', label='Canonical (active)'),\n    mpatches.Patch(facecolor='#F44336', edgecolor='black', label='Non-canonical (disrupted)'),\n]\nax2.legend(handles=legend_elements, loc='upper right', fontsize=10)\n\n# Add protein labels\nfor i, prot in enumerate(proteins):\n    ax2.text(1 + i * bar_width, 1.15, prot, ha='center', fontsize=9, fontweight='bold')\n\n# Add annotation about the critical finding\nax2.annotate('Critical: His\u2192Tyr\\nabolishes Fe(II) binding', \n            xy=(2.4, 0.9), xytext=(2.7, 1.3),\n            arrowprops=dict(arrowstyle='->', color='red', lw=2),\n            fontsize=10, color='red', fontweight='bold',\n            bbox=dict(boxstyle='round,pad=0.3', facecolor='lightyellow', edgecolor='red'))\n\nplt.tight_layout()\nplt.savefig('evidence_matrix.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Evidence matrix saved.\")\n",
  "plot_number": 1
}