{"spec_id":"ma-differential-expression","library":"makie","language":"julia","code":"# anyplot.ai\n# ma-differential-expression: MA Plot for Differential Expression\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 88/100 | Created: 2026-06-21\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# Theme tokens\nconst THEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nconst INK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst INK_MUTED   = THEME == \"light\" ? colorant\"#6B6A63\" : colorant\"#A8A79F\"\n\n# Imprint palette positions used in this plot\nconst BRAND_GREEN = colorant\"#009E73\"  # position 1 — up-regulated (gain)\nconst MATTE_RED   = colorant\"#AE3030\"  # semantic anchor — down-regulated (loss)\nconst OCHRE       = colorant\"#BD8233\"  # position 4 — LOESS trend line\n\n# Data — simulated RNA-seq differential expression (~15 000 genes)\nn_genes = 15_000\n\n# A-values: mean log2 expression (funnel-shaped distribution typical of RNA-seq)\nmean_expr = abs.(randn(n_genes)) .* 3.5 .+ abs.(randn(n_genes)) .* 1.0\nmean_expr = clamp.(mean_expr, 0.05, 14.5)\n\n# M-values: LFC variance shrinks at higher expression\nlfc_noise = (2.0 ./ (mean_expr .+ 0.8)) .+ 0.18\nlfc = randn(n_genes) .* lfc_noise\n\n# Slight upward bias at low expression — common normalization artifact\nlfc .+= 0.25 .* exp.(-mean_expr ./ 3.5)\n\n# Inject ~10 % truly differentially expressed genes\nn_de    = 1_500\nde_idx  = randperm(n_genes)[1:n_de]\nhalf_de = div(n_de, 2)\nfor i in 1:half_de\n    lfc[de_idx[i]] += 1.9 + abs(randn()) * 0.6\nend\nfor i in (half_de + 1):n_de\n    lfc[de_idx[i]] -= 1.9 + abs(randn()) * 0.6\nend\nlfc = clamp.(lfc, -7.5, 7.5)\n\nsignificant = falses(n_genes)\nsignificant[de_idx] .= true\n\nnot_sig  = .!significant\nsig_up   = significant .& (lfc .>  0.0)\nsig_down = significant .& (lfc .<= 0.0)\n\n# Gaussian kernel smoothing — LOESS approximation (inline, no function)\nn_eval   = 120\nbw       = 1.5\nx_eval   = collect(range(minimum(mean_expr), maximum(mean_expr), length=n_eval))\ny_smooth = zeros(n_eval)\nfor i in eachindex(x_eval)\n    w       = exp.(-((mean_expr .- x_eval[i]) ./ bw) .^ 2)\n    wsum    = sum(w)\n    y_smooth[i] = wsum > 1e-10 ? sum(w .* lfc) / wsum : 0.0\nend\n\n# Figure\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"ma-differential-expression · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Mean log₂ Expression\",\n    ylabel             = \"log₂ Fold Change\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridvisible       = false,\n    ygridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.10),\n    xminorgridvisible  = false,\n    yminorgridvisible  = false,\n)\n\n# Layer 1: non-significant genes (large cloud, semi-transparent)\nscatter!(ax, mean_expr[not_sig], lfc[not_sig];\n    color       = (INK_MUTED, 0.18),\n    markersize  = 4,\n    strokewidth = 0,\n)\n\n# Layer 2: significantly up-regulated genes (brand green — gain)\nscatter!(ax, mean_expr[sig_up], lfc[sig_up];\n    color       = (BRAND_GREEN, 0.65),\n    markersize  = 9,\n    strokewidth = 0.5,\n    strokecolor = INK_SOFT,\n)\n\n# Layer 3: significantly down-regulated genes (matte red — loss)\nscatter!(ax, mean_expr[sig_down], lfc[sig_down];\n    color       = (MATTE_RED, 0.65),\n    markersize  = 9,\n    strokewidth = 0.5,\n    strokecolor = INK_SOFT,\n)\n\n# Reference lines: zero line and ±1 log2 FC thresholds\nhlines!(ax, [0.0]; color = INK_SOFT, linewidth = 1.5)\nhlines!(ax, [1.0, -1.0]; color = INK_SOFT, linewidth = 0.9, linestyle = :dash)\n\n# LOESS-like smoothing curve\nlines!(ax, x_eval, y_smooth; color = OCHRE, linewidth = 3.0)\n\n# Legend\nLegend(\n    fig[1, 2],\n    [\n        MarkerElement(\n            color = RGBAf(INK_MUTED.r, INK_MUTED.g, INK_MUTED.b, 0.55),\n            marker = :circle, markersize = 14,\n        ),\n        MarkerElement(color = BRAND_GREEN, marker = :circle, markersize = 14),\n        MarkerElement(color = MATTE_RED,   marker = :circle, markersize = 14),\n        LineElement(color = OCHRE, linewidth = 2.5),\n    ],\n    [\n        \"Not significant\",\n        \"Up-regulated (adj. p < 0.05)\",\n        \"Down-regulated (adj. p < 0.05)\",\n        \"LOESS trend\",\n    ],\n    framevisible    = true,\n    framecolor      = INK_SOFT,\n    backgroundcolor = ELEVATED_BG,\n    labelcolor      = INK,\n    labelsize       = 14,\n)\n\ncolsize!(fig.layout, 1, Relative(0.78))\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}