{"spec_id":"manhattan-gwas","library":"makie","language":"julia","code":"# anyplot.ai\n# manhattan-gwas: Manhattan Plot for GWAS\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 88/100 | Created: 2026-09-05\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# Theme tokens (see prompts/default-style-guide.md \"Theme-adaptive Chrome\")\nTHEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nPAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nINK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nINK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nINK_MUTED   = THEME == \"light\" ? colorant\"#6B6A63\" : colorant\"#A8A79F\"\n\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\", colorant\"#C475FD\", colorant\"#4467A3\", colorant\"#BD8233\",\n    colorant\"#AE3030\", colorant\"#2ABCCD\", colorant\"#954477\", colorant\"#99B314\",\n]\nCHR_COLOR_ODD  = IMPRINT_PALETTE[1]  # brand green\nCHR_COLOR_EVEN = IMPRINT_PALETTE[3]  # blue\nAMBER          = colorant\"#DDCC77\"   # significant-hit highlight\n\n# Data: simulated GWAS summary statistics across the 22 autosomes + chromosome X\nchrom_names = vcat(string.(1:22), \"X\")\nchrom_lengths_mb = Float64[\n    249, 243, 198, 191, 180, 171, 159, 145, 138, 134, 135, 133,\n    114, 107, 102, 90, 83, 80, 59, 64, 47, 51, 156,\n]\nsnps_per_mb = 36.0\npeak_chroms = (\"2\", \"6\", \"9\", \"17\", \"X\")\n\nchrom_ids  = String[]\npositions  = Float64[]\nneglog10p  = Float64[]\nchrom_centers = Float64[]\n\ntop_hit_pos    = Float64[]\ntop_hit_p      = Float64[]\ntop_hit_labels = String[]\n\ncumulative_offset = 0.0\nfor (name, length_mb) in zip(chrom_names, chrom_lengths_mb)\n    n_snps = round(Int, length_mb * snps_per_mb)\n    local_pos = sort(rand(n_snps) .* length_mb)\n    baseline_p = -log10.(rand(n_snps))  # null distribution — mostly non-significant\n\n    if name in peak_chroms\n        peak_center = length_mb * rand()\n        peak_width = length_mb * 0.015\n        peak_signal = 12.0 .* exp.(-((local_pos .- peak_center) .^ 2) ./ (2 * peak_width^2))\n        baseline_p = baseline_p .+ peak_signal .* (0.5 .+ 0.5 .* rand(n_snps))\n\n        top_idx = argmax(baseline_p)\n        push!(top_hit_pos, local_pos[top_idx] + cumulative_offset)\n        push!(top_hit_p, baseline_p[top_idx])\n        push!(top_hit_labels, \"rs\" * string(rand(1_000_000:99_999_999)))\n    end\n\n    append!(chrom_ids, fill(name, n_snps))\n    append!(positions, local_pos .+ cumulative_offset)\n    append!(neglog10p, baseline_p)\n    push!(chrom_centers, cumulative_offset + length_mb / 2)\n\n    global cumulative_offset += length_mb\nend\n\npoint_colors = [isodd(parse_index) ? CHR_COLOR_ODD : CHR_COLOR_EVEN\n                for parse_index in indexin(chrom_ids, chrom_names)]\n\ngenome_wide_threshold = -log10(5e-8)   # ≈ 7.30 — genome-wide significance\nsuggestive_threshold  = -log10(1e-5)   # 5.0 — suggestive association\n\nsignificant = neglog10p .> genome_wide_threshold\n\n# Plot — see default-style-guide.md \"Visual Sizing Defaults\" for the canvas + sizing values\ntitle_text = \"manhattan-gwas · julia · makie · anyplot.ai\"\n\nfig = Figure(\n    resolution      = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = title_text,\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Chromosome\",\n    ylabel             = \"-log10(p-value)\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 10,\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.12),\n    yminorgridvisible  = false,\n)\nax.xticks = (chrom_centers, chrom_names)\n\nscatter!(\n    ax, positions, neglog10p;\n    color = point_colors, markersize = 3, alpha = 0.6, strokewidth = 0,\n)\nscatter!(\n    ax, positions[significant], neglog10p[significant];\n    color = AMBER, markersize = 8, strokewidth = 0.6, strokecolor = INK,\n    label = \"Genome-wide significant SNP\",\n)\n\ntext!(\n    ax, top_hit_pos, top_hit_p .+ 0.6;\n    text = top_hit_labels, color = INK_SOFT, fontsize = 11,\n    align = (:center, :bottom),\n)\n\n# Extra headroom above the tallest peak/label keeps the top-left legend box\n# (pixel-anchored) clear of the chromosome-2 peak, which otherwise sits\n# closest to the axis top among the labeled hits.\nylims!(ax, -0.3, maximum(neglog10p) + 2.5)\n\nhlines!(\n    ax, [suggestive_threshold];\n    color = INK_MUTED, linestyle = :dot, linewidth = 2,\n    label = \"Suggestive (p < 1×10⁻⁵)\",\n)\nhlines!(\n    ax, [genome_wide_threshold];\n    color = AMBER, linestyle = :dash, linewidth = 2.5,\n    label = \"Genome-wide significance (p < 5×10⁻⁸)\",\n)\n\naxislegend(\n    ax; position = :lt, backgroundcolor = ELEVATED_BG, framevisible = false,\n    labelcolor = INK, labelsize = 11, patchsize = (18, 4),\n)\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}