{"spec_id":"ma-differential-expression","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nma-differential-expression: MA Plot for Differential Expression\nLibrary: plotnine 0.15.7 | Python 3.13.14\nQuality: 86/100 | Updated: 2026-06-21\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    annotate,\n    element_blank,\n    element_line,\n    element_rect,\n    element_text,\n    geom_hline,\n    geom_point,\n    geom_text,\n    ggplot,\n    guide_legend,\n    guides,\n    labs,\n    scale_alpha_manual,\n    scale_color_manual,\n    scale_shape_manual,\n    scale_size_manual,\n    stat_smooth,\n    theme,\n    theme_minimal,\n)\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Semantic Imprint palette: green=gain, matte-red=loss, muted=background noise\nCOLOR_UP = \"#009E73\"  # Imprint position 1 — upregulation (positive/gain)\nCOLOR_DOWN = \"#AE3030\"  # Imprint position 5 — downregulation (loss/error)\nCOLOR_NS = INK_MUTED  # theme-adaptive muted — non-significant genes\n\n# Data — T-cell activation study (activated vs resting), immunology domain\nnp.random.seed(42)\nn_genes = 15000\n\nmean_expression = np.random.uniform(0, 15, n_genes)\nlog_fold_change = np.random.normal(0, 0.5, n_genes)\nlog_fold_change += 0.12 * np.sin(mean_expression * 0.25)\n\nn_sig = int(n_genes * 0.08)\nsig_indices = np.random.choice(n_genes, n_sig, replace=False)\nlog_fold_change[sig_indices] *= np.random.uniform(2.5, 5.0, n_sig)\n\nsignificant = np.abs(log_fold_change) > 1.0\nsignificant[sig_indices[: n_sig // 2]] = True\n\ncategory = np.where(~significant, \"Not significant\", np.where(log_fold_change > 0, \"Upregulated\", \"Downregulated\"))\n\n# Immunology genes — T-cell activation markers, ranked by p-value proxy (|LFC| × sqrt(baseMean))\ngene_names = [f\"Gene{i}\" for i in range(n_genes)]\npvalue_score = np.abs(log_fold_change) * np.sqrt(mean_expression + 1)\nimmune_genes = [\"IL2\", \"IFNG\", \"IL4\", \"FOXP3\", \"CD69\", \"TNF\", \"GATA3\", \"TBX21\"]\ntop_idx = np.argsort(pvalue_score)[-len(immune_genes) :]\nfor i, idx in enumerate(top_idx):\n    gene_names[idx] = immune_genes[i]\n\ndf = pd.DataFrame(\n    {\n        \"mean_expression\": mean_expression,\n        \"log_fold_change\": log_fold_change,\n        \"significant\": significant,\n        \"gene_name\": gene_names,\n        \"category\": pd.Categorical(\n            category, categories=[\"Downregulated\", \"Not significant\", \"Upregulated\"], ordered=True\n        ),\n    }\n)\n\ndf_labels = df.loc[top_idx].copy()\nnudge = np.where(df_labels[\"log_fold_change\"] > 0, 0.7, -0.7)\ndf_labels[\"label_y\"] = df_labels[\"log_fold_change\"] + nudge\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"mean_expression\", y=\"log_fold_change\", color=\"category\", shape=\"category\"))\n    + geom_point(aes(alpha=\"category\", size=\"category\"), stroke=0)\n    + geom_hline(yintercept=0, color=INK, size=0.8, alpha=0.5)\n    + geom_hline(yintercept=1, linetype=\"dashed\", color=INK_SOFT, size=0.5)\n    + geom_hline(yintercept=-1, linetype=\"dashed\", color=INK_SOFT, size=0.5)\n    + annotate(\n        \"label\",\n        x=14.5,\n        y=1.0,\n        label=\" ±2-fold threshold \",\n        size=3.0,\n        color=INK_SOFT,\n        fill=ELEVATED_BG,\n        alpha=0.9,\n        label_size=0,\n        ha=\"right\",\n        va=\"center\",\n    )\n    + stat_smooth(aes(group=1), method=\"lowess\", color=\"#4467A3\", size=1.2, se=False, span=0.3, linetype=\"solid\")\n    + geom_text(\n        aes(x=\"mean_expression\", y=\"label_y\", label=\"gene_name\"),\n        data=df_labels,\n        color=INK,\n        size=3.5,\n        fontstyle=\"italic\",\n        inherit_aes=False,\n        show_legend=False,\n    )\n    + scale_color_manual(values={\"Upregulated\": COLOR_UP, \"Not significant\": COLOR_NS, \"Downregulated\": COLOR_DOWN})\n    + scale_alpha_manual(values={\"Upregulated\": 0.8, \"Not significant\": 0.15, \"Downregulated\": 0.8})\n    + scale_shape_manual(values={\"Upregulated\": \"^\", \"Not significant\": \"o\", \"Downregulated\": \"v\"})\n    + scale_size_manual(values={\"Upregulated\": 2.0, \"Not significant\": 1.0, \"Downregulated\": 2.0})\n    + labs(\n        x=\"Mean Expression (A)\",\n        y=\"Log₂ Fold Change (M)\",\n        title=\"ma-differential-expression · python · plotnine · anyplot.ai\",\n        color=\"\",\n        shape=\"\",\n    )\n    + guides(\n        color=guide_legend(override_aes={\"alpha\": 1, \"size\": 3}),\n        shape=guide_legend(override_aes={\"alpha\": 1, \"size\": 3}),\n        alpha=\"none\",\n        size=\"none\",\n    )\n    + theme_minimal()\n    + theme(\n        figure_size=(8, 4.5),\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        panel_grid_major=element_line(color=INK, size=0.3, alpha=0.15),\n        panel_grid_minor=element_blank(),\n        axis_title=element_text(size=10, color=INK),\n        axis_text=element_text(size=8, color=INK_SOFT),\n        plot_title=element_text(size=12, weight=\"bold\", color=INK),\n        legend_text=element_text(size=8, color=INK_SOFT),\n        legend_title=element_blank(),\n        legend_position=\"top\",\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n    )\n)\n\n# Save\nplot.save(f\"plot-{THEME}.png\", dpi=400, width=8, height=4.5, units=\"in\", verbose=False)\n"}