{"spec_id":"genome-track-multi","library":"makie","language":"julia","code":"# anyplot.ai\n# genome-track-multi: Genome Track Viewer\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 90/100 | Created: 2026-06-02\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# Theme tokens — Imprint palette, theme-adaptive chrome\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\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\",  # 1 — brand green\n    colorant\"#C475FD\",  # 2 — lavender\n    colorant\"#4467A3\",  # 3 — blue\n    colorant\"#BD8233\",  # 4 — ochre\n    colorant\"#AE3030\",  # 5 — matte red (semantic: variants/mutations)\n    colorant\"#2ABCCD\",  # 6 — cyan\n    colorant\"#954477\",  # 7 — rose\n    colorant\"#99B314\",  # 8 — lime\n]\n\n# Genomic region: chr7, CFTR-like locus (simplified coordinates)\nreg_start = 1_000\nreg_end   = 11_000\n\n# Gene track — two genes on opposite strands\nga_exon_starts = [1500, 2900, 4300, 5900, 7200]\nga_exon_ends   = [2100, 3500, 5000, 6700, 8000]\nga_gene_start  = 1500\nga_gene_end    = 8000\nga_y           = 0.55\n\ngb_exon_starts = [8300, 9100, 9800, 10300]\ngb_exon_ends   = [8800, 9500, 10050, 10700]\ngb_gene_start  = 8300\ngb_gene_end    = 10700\ngb_y           = -0.45\n\n# Coverage track (read depth peaks over exon regions)\ncov_pos   = collect(range(Float64(reg_start), Float64(reg_end), length = 400))\ncov_depth = fill(8.0, 400)\nfor (es, ee) in zip(ga_exon_starts, ga_exon_ends)\n    mask = (cov_pos .>= es) .& (cov_pos .<= ee)\n    cov_depth[mask] .+= 48.0 .+ randn(sum(mask)) .* 9.0\nend\nfor (es, ee) in zip(gb_exon_starts, gb_exon_ends)\n    mask = (cov_pos .>= es) .& (cov_pos .<= ee)\n    cov_depth[mask] .+= 36.0 .+ randn(sum(mask)) .* 7.0\nend\ncov_depth .= max.(0.0, cov_depth .+ randn(400) .* 2.0)\n\n# Variant track — SNP positions with quality scores\nsnp_pos = sort(rand(reg_start:reg_end, 13))\nsnp_q   = rand(28:99, 13)\n\n# Regulatory elements: (start, end, label, palette color)\nreg_els = [\n    (1000, 1600, \"Promoter\", IMPRINT_PALETTE[1]),\n    (4700, 5300, \"Enhancer\", IMPRINT_PALETTE[3]),\n    (7100, 7600, \"CTCF\",     IMPRINT_PALETTE[4]),\n    (9600, 10100,\"Enhancer\", IMPRINT_PALETTE[3]),\n]\n\n# Title (60 chars < 67 baseline → default titlesize = 20)\ntitle_str = \"CFTR Locus · genome-track-multi · julia · makie · anyplot.ai\"\ntitlesize = max(14, round(Int, 20 * min(1.0, 67.0 / length(title_str))))\n\ngrid_col = RGBAf(INK.r, INK.g, INK.b, 0.12)\n\n# Figure\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 12,\n    backgroundcolor = PAGE_BG,\n)\n\n# Title label above all tracks\nLabel(\n    fig[0, 1];\n    text      = title_str,\n    fontsize  = titlesize,\n    color     = INK,\n    font      = :bold,\n    tellwidth = false,\n    padding   = (0, 0, 4, 2),\n)\n\n# ---- Track 1: Gene Annotations ----------------------------------------\nax_gene = Axis(\n    fig[1, 1];\n    ylabel             = \"Genes\",\n    ylabelsize         = 12,\n    ylabelcolor        = INK,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    bottomspinevisible = false,\n    leftspinecolor     = INK_SOFT,\n    xgridvisible       = false,\n    ygridvisible       = false,\n    yticklabelsvisible = false,\n    yticksvisible      = false,\n    limits             = (reg_start, reg_end, -1.3, 1.4),\n)\nhidexdecorations!(ax_gene; ticks = false, grid = false)\n\n# Gene A — backbone + exon rectangles + strand arrows\nlines!(ax_gene, [Float64(ga_gene_start), Float64(ga_gene_end)], [ga_y, ga_y];\n    color = INK_SOFT, linewidth = 1.5)\n\nfor (s, e) in zip(ga_exon_starts, ga_exon_ends)\n    poly!(ax_gene,\n        [Point2f(s, ga_y - 0.22), Point2f(e, ga_y - 0.22),\n         Point2f(e, ga_y + 0.22), Point2f(s, ga_y + 0.22)];\n        color = IMPRINT_PALETTE[1], strokewidth = 0)\nend\n\nfor xp in (ga_gene_start + 500):1000:ga_gene_end\n    scatter!(ax_gene, [Float64(xp)], [ga_y + 0.46];\n        marker = :rtriangle, color = INK_MUTED, markersize = 7, strokewidth = 0)\nend\n\ntext!(ax_gene, Float64(ga_gene_start), ga_y + 0.72;\n    text = \"CFTR-A  (+)\", fontsize = 11, color = INK, align = (:left, :center),\n    font = :bold)\n\n# Gene B — backbone + exon rectangles + strand arrows\nlines!(ax_gene, [Float64(gb_gene_start), Float64(gb_gene_end)], [gb_y, gb_y];\n    color = INK_SOFT, linewidth = 1.5)\n\nfor (s, e) in zip(gb_exon_starts, gb_exon_ends)\n    poly!(ax_gene,\n        [Point2f(s, gb_y - 0.22), Point2f(e, gb_y - 0.22),\n         Point2f(e, gb_y + 0.22), Point2f(s, gb_y + 0.22)];\n        color = IMPRINT_PALETTE[1], strokewidth = 0)\nend\n\nfor xp in (gb_gene_end - 400):-1000:gb_gene_start\n    scatter!(ax_gene, [Float64(xp)], [gb_y - 0.46];\n        marker = :ltriangle, color = INK_MUTED, markersize = 7, strokewidth = 0)\nend\n\ntext!(ax_gene, Float64(gb_gene_end), gb_y - 0.73;\n    text = \"CFTR-B  (−)\", fontsize = 11, color = INK, align = (:right, :center),\n    font = :bold)\n\n# ---- Track 2: Read Coverage -------------------------------------------\nax_cov = Axis(\n    fig[2, 1];\n    ylabel             = \"Read Depth\",\n    ylabelsize         = 12,\n    ylabelcolor        = INK,\n    yticklabelcolor    = INK_SOFT,\n    yticklabelsize     = 10,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = ELEVATED_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    bottomspinevisible = false,\n    leftspinecolor     = INK_SOFT,\n    xgridvisible       = false,\n    ygridcolor         = grid_col,\n    yticks             = [0, 25, 50],\n)\nhidexdecorations!(ax_cov; ticks = false, grid = false)\n\nband!(ax_cov, cov_pos, fill(0.0, 400), cov_depth;\n    color = RGBAf(IMPRINT_PALETTE[3].r, IMPRINT_PALETTE[3].g, IMPRINT_PALETTE[3].b, 0.30))\nlines!(ax_cov, cov_pos, cov_depth;\n    color = IMPRINT_PALETTE[3], linewidth = 1.5)\n\n# ---- Track 3: Variants (SNPs, lollipop plot) -------------------------\nax_var = Axis(\n    fig[3, 1];\n    ylabel             = \"Variants\",\n    ylabelsize         = 12,\n    ylabelcolor        = INK,\n    yticklabelcolor    = INK_SOFT,\n    yticklabelsize     = 10,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    bottomspinevisible = false,\n    leftspinecolor     = INK_SOFT,\n    xgridvisible       = false,\n    ygridvisible       = false,\n    limits             = (reg_start, reg_end, 0.0, 115.0),\n    yticks             = [0, 50, 100],\n)\nhidexdecorations!(ax_var; ticks = false, grid = false)\n\nfor (pos, q) in zip(snp_pos, snp_q)\n    lines!(ax_var, [Float64(pos), Float64(pos)], [0.0, Float64(q)];\n        color = INK_SOFT, linewidth = 1.2)\n    scatter!(ax_var, [Float64(pos)], [Float64(q)];\n        color = IMPRINT_PALETTE[5], markersize = 9, strokewidth = 0)\nend\n\ntext!(ax_var, Float64(reg_start + 100), 110.0;\n    text = \"Quality score\", fontsize = 12, color = INK_MUTED, align = (:left, :top))\n\n# ---- Track 4: Regulatory Elements ------------------------------------\nax_reg = Axis(\n    fig[4, 1];\n    xlabel             = \"chr7 position (bp)\",\n    ylabel             = \"Regulatory\",\n    xlabelsize         = 12,\n    ylabelsize         = 12,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelcolor    = INK_SOFT,\n    xticklabelsize     = 10,\n    xtickcolor         = INK_SOFT,\n    backgroundcolor    = ELEVATED_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridvisible       = false,\n    ygridvisible       = false,\n    limits             = (reg_start, reg_end, 0.0, 1.0),\n    yticklabelsvisible = false,\n    yticksvisible      = false,\n)\n\nfor (s, e, lbl, clr) in reg_els\n    poly!(ax_reg,\n        [Point2f(s, 0.2), Point2f(e, 0.2), Point2f(e, 0.8), Point2f(s, 0.8)];\n        color = (clr, 0.80), strokewidth = 0)\n    text!(ax_reg, (s + e) / 2.0, 0.5;\n        text = lbl, fontsize = 10, color = INK,\n        align = (:center, :center), font = :bold)\nend\n\n# Link x-axes and enforce shared range\nlinkxaxes!(ax_gene, ax_cov, ax_var, ax_reg)\nxlims!(ax_gene, Float64(reg_start), Float64(reg_end))\nxlims!(ax_cov,  Float64(reg_start), Float64(reg_end))\nxlims!(ax_var,  Float64(reg_start), Float64(reg_end))\nxlims!(ax_reg,  Float64(reg_start), Float64(reg_end))\n\n# Row proportions\nrowsize!(fig.layout, 0, Fixed(38))\nrowsize!(fig.layout, 1, Relative(0.28))\nrowsize!(fig.layout, 2, Relative(0.31))\nrowsize!(fig.layout, 3, Relative(0.22))\nrowsize!(fig.layout, 4, Relative(0.19))\nrowgap!(fig.layout, 4)\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}