{
  "filename": "plot_3.png",
  "iteration": 1,
  "description": "Create publication-quality alignment figure of JAMM catalytic region showing residue substitutions in NPLOC4",
  "timestamp": "2026-06-22 02:05:52",
  "code": "\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as mpatches\nimport numpy as np\n\n# Create a final publication-quality alignment figure showing the JAMM region\nfig, ax = plt.subplots(figsize=(16, 8))\nax.axis('off')\n\n# Define the aligned sequences around the GW motif (core JAMM region)\n# Aligned at GW position, showing \u00b115 residues\nsequences = {\n    'PSMD14 (MPN+ ACTIVE)':  {'aligned': 'EMVVGWYHSHPGFGCWLSGVD', 'gw_pos': 4, 'status': 'active'},\n    'BRCC3 (MPN+ ACTIVE)':   {'aligned': 'MRVVGWYHSHPHITVWPSHVD', 'gw_pos': 4, 'status': 'active'},\n    'PSMD7 (MPN- pseudo)':   {'aligned': 'RIVGWYHTGPKLHKNDIAINEL', 'gw_pos': 3, 'status': 'inactive'},\n    'CSN6 (MPN- pseudo)':    {'aligned': 'EFLGWYTTGGPPDPSDIHVHKQ', 'gw_pos': 3, 'status': 'inactive'},\n    'EIF3F (MPN- pseudo)':   {'aligned': 'LILGWYATGHDITEHSVLIHE', 'gw_pos': 3, 'status': 'inactive'},\n    'NPLOC4 (MPN- TARGET)':  {'aligned': 'RKVGWIFTDLVSEDTRKGTVR', 'gw_pos': 3, 'status': 'target'},\n    'Npl4-yeast (MPN-)':     {'aligned': 'FIQAWRYTGMQRFGYMYGSQP', 'gw_pos': 3, 'status': 'inactive'},\n}\n\ny_start = 0.92\ny_step = 0.09\nx_start = 0.15\nchar_width = 0.032\n\n# Title\nax.text(0.5, 0.98, 'JAMM Catalytic Region Alignment', \n        ha='center', va='top', fontsize=16, fontweight='bold', transform=ax.transAxes)\nax.text(0.5, 0.94, 'Aligned at conserved GW motif | Active DUBs show H[ST]H zinc-binding pair', \n        ha='center', va='top', fontsize=11, style='italic', color='gray', transform=ax.transAxes)\n\n# JAMM motif position markers (relative to GW at position 4)\n# In active DUBs: GW(pos 4) Y(5) H(6) S(7) H(8) ... D(19)\njamm_positions = {6: 'H\u2081\\n(Zn)', 7: 'S/T', 8: 'H\u2082\\n(Zn)', 19: 'D\\n(Zn)'}\n\nfor i, (name, info) in enumerate(sequences.items()):\n    y = y_start - (i + 1) * y_step\n    seq = info['aligned']\n    status = info['status']\n    \n    # Protein name\n    if status == 'active':\n        name_color = '#27ae60'\n        name_weight = 'bold'\n    elif status == 'target':\n        name_color = '#c0392b'\n        name_weight = 'bold'\n    else:\n        name_color = '#7f8c8d'\n        name_weight = 'normal'\n    \n    ax.text(x_start - 0.01, y, name, ha='right', va='center', fontsize=10,\n            fontweight=name_weight, color=name_color, transform=ax.transAxes,\n            family='monospace')\n    \n    # Sequence characters\n    for j, char in enumerate(seq):\n        x = x_start + j * char_width\n        \n        # Color based on JAMM relevance\n        if status in ['active'] and j in [6, 7, 8]:  # HSH positions\n            bg_color = '#27ae60'\n            text_color = 'white'\n            fontweight = 'bold'\n        elif status in ['active'] and j == 19:  # D position\n            bg_color = '#2980b9'\n            text_color = 'white'\n            fontweight = 'bold'\n        elif status == 'target' and j in [6, 7, 8, 19]:  # Where JAMM should be in NPLOC4\n            bg_color = '#e74c3c'\n            text_color = 'white'\n            fontweight = 'bold'\n        elif j in [4, 5]:  # GW position\n            bg_color = '#f39c12'\n            text_color = 'white'\n            fontweight = 'bold'\n        else:\n            bg_color = 'white'\n            text_color = 'black'\n            fontweight = 'normal'\n        \n        # Draw background box\n        rect = mpatches.FancyBboxPatch((x - char_width/2, y - 0.02), char_width, 0.04,\n                                        boxstyle=\"round,pad=0.001\", \n                                        facecolor=bg_color, edgecolor='#bdc3c7',\n                                        linewidth=0.5, transform=ax.transAxes)\n        ax.add_patch(rect)\n        \n        ax.text(x, y, char, ha='center', va='center', fontsize=11,\n                fontweight=fontweight, color=text_color, transform=ax.transAxes,\n                family='monospace')\n\n# Position labels on top\nfor j in range(21):\n    x = x_start + j * char_width\n    if j in [4, 5]:\n        label = 'GW' if j == 4 else ''\n    elif j in jamm_positions:\n        label = jamm_positions[j]\n    else:\n        label = ''\n    \n    if label:\n        ax.text(x, y_start + 0.01, label, ha='center', va='bottom', fontsize=8,\n                fontweight='bold', color='#2c3e50', transform=ax.transAxes)\n\n# Legend\nlegend_y = 0.08\nlegend_items = [\n    ('#f39c12', 'Conserved GW motif'),\n    ('#27ae60', 'JAMM catalytic residues (H, S, H) in active DUBs'),\n    ('#2980b9', 'Zinc-coordinating Asp in active DUBs'),\n    ('#e74c3c', 'ABSENT catalytic residues in NPLOC4 (F, T, D instead of H, S, H)'),\n]\n\nfor k, (color, label) in enumerate(legend_items):\n    rect = mpatches.FancyBboxPatch((0.15, legend_y - k * 0.035 - 0.01), 0.02, 0.02,\n                                    boxstyle=\"round,pad=0.001\",\n                                    facecolor=color, edgecolor='#bdc3c7',\n                                    transform=ax.transAxes)\n    ax.add_patch(rect)\n    ax.text(0.18, legend_y - k * 0.035, label, ha='left', va='center', fontsize=9,\n            transform=ax.transAxes)\n\n# Add verdict box\nverdict_text = (\"VERDICT: NPLOC4 lacks all JAMM catalytic residues\\n\"\n                \"H\u2192F, S\u2192T, H\u2192D at zinc-binding positions\\n\"\n                \"Classification: MPN- (catalytically inactive pseudo-DUB)\")\nprops = dict(boxstyle='round,pad=0.5', facecolor='#fadbd8', edgecolor='#e74c3c', alpha=0.9)\nax.text(0.75, 0.08, verdict_text, transform=ax.transAxes, fontsize=9,\n        va='center', ha='center', bbox=props, fontweight='bold')\n\nplt.tight_layout()\nplt.savefig('jamm_alignment_final.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Final JAMM alignment figure saved\")\n",
  "plot_number": 3
}