{"spec_id":"network-bipartite","library":"makie","language":"julia","code":"# anyplot.ai\n# network-bipartite: Bipartite Network Graph\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 91/100 | Created: 2026-09-05\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 INK      = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\", colorant\"#C475FD\", colorant\"#4467A3\", colorant\"#BD8233\",\n    colorant\"#AE3030\", colorant\"#2ABCCD\", colorant\"#954477\", colorant\"#99B314\",\n]\nconst GENE_COLOR    = IMPRINT_PALETTE[1]  # brand green — set A (always first series)\nconst DISEASE_COLOR = IMPRINT_PALETTE[3]  # blue — set B\n\n# --- Data ---------------------------------------------------------------------\ngenes = [\"APOE\", \"TP53\", \"BRCA1\", \"BRCA2\", \"MTHFR\", \"CFTR\", \"HTT\", \"LRRK2\",\n         \"PSEN1\", \"SOD1\", \"FMR1\", \"DMD\", \"HBB\", \"INS\"]\ndiseases = [\"Alzheimer's Disease\", \"Breast Cancer\", \"Cystic Fibrosis\",\n            \"Huntington's Disease\", \"Parkinson's Disease\", \"ALS\",\n            \"Fragile X Syndrome\", \"Muscular Dystrophy\", \"Sickle Cell Anemia\",\n            \"Type 1 Diabetes\"]\n\nn_genes    = length(genes)\nn_diseases = length(diseases)\n\nedges = Tuple{Int,Int,Float64}[]\nfor gi in 1:n_genes\n    n_links = rand(2:4)\n    targets = randperm(n_diseases)[1:n_links]\n    for di in targets\n        association_strength = 0.3 + 0.7 * rand()\n        push!(edges, (gi, di, association_strength))\n    end\nend\n\ngene_degree    = zeros(Int, n_genes)\ndisease_degree = zeros(Int, n_diseases)\nfor (gi, di, _) in edges\n    gene_degree[gi]    += 1\n    disease_degree[di] += 1\nend\n\ngene_x    = fill(0.0, n_genes)\ndisease_x = fill(1.0, n_diseases)\ngene_y    = [(n_genes - 1) / 2 - (i - 1) for i in 1:n_genes]\ndisease_y = [(n_diseases - 1) / 2 - (i - 1) for i in 1:n_diseases]\n\nweights = [w for (_, _, w) in edges]\nmin_w, max_w = minimum(weights), maximum(weights)\n\n# --- Plot -----------------------------------------------------------------\nfig = Figure(\n    resolution      = (1600, 900),\n    backgroundcolor = PAGE_BG,\n)\n\ntitle_str = \"network-bipartite · julia · makie · anyplot.ai\"\nmax_y = (max(n_genes, n_diseases) - 1) / 2 + 1.6\n\nax = Axis(\n    fig[1, 1];\n    title               = title_str,\n    titlesize           = 20,\n    titlecolor          = INK,\n    backgroundcolor     = PAGE_BG,\n    xgridvisible        = false,\n    ygridvisible        = false,\n    xticksvisible       = false,\n    yticksvisible       = false,\n    xticklabelsvisible  = false,\n    yticklabelsvisible  = false,\n    topspinevisible     = false,\n    rightspinevisible   = false,\n    leftspinevisible    = false,\n    bottomspinevisible  = false,\n    xautolimitmargin    = (0.0, 0.0),\n    yautolimitmargin    = (0.0, 0.0),\n)\nxlims!(ax, -0.95, 1.85)\nylims!(ax, -max_y, max_y)\n\n# Edges: one vectorized linesegments! call instead of a per-edge lines! loop —\n# per-segment color/linewidth vectors drive the association-strength encoding.\nedge_points  = Point2f[]\nedge_colors  = RGBAf[]\nedge_widths  = Float64[]\nfor (gi, di, w) in edges\n    norm_w     = (w - min_w) / (max_w - min_w)\n    edge_alpha = 0.12 + 0.55 * norm_w\n    edge_width = 0.8 + 2.6 * norm_w\n    edge_color = RGBAf(INK.r, INK.g, INK.b, edge_alpha)\n    push!(edge_points, Point2f(gene_x[gi], gene_y[gi]), Point2f(disease_x[di], disease_y[di]))\n    push!(edge_colors, edge_color, edge_color)\n    push!(edge_widths, edge_width, edge_width)\nend\nlinesegments!(ax, edge_points; color = edge_colors, linewidth = edge_widths)\n\n# Node size encodes degree (number of connections) — highlights hub genes/diseases.\ngene_sizes    = 17 .+ 3.8 .* gene_degree\ndisease_sizes = 17 .+ 3.8 .* disease_degree\n\nscatter!(ax, gene_x, gene_y;\n         color = GENE_COLOR, markersize = gene_sizes,\n         strokewidth = 1.5, strokecolor = PAGE_BG, label = \"Genes\")\nscatter!(ax, disease_x, disease_y;\n         color = DISEASE_COLOR, markersize = disease_sizes,\n         strokewidth = 1.5, strokecolor = PAGE_BG, label = \"Diseases\")\n\nfor i in 1:n_genes\n    text!(ax, gene_x[i] - 0.05, gene_y[i];\n          text = genes[i], align = (:right, :center), color = INK, fontsize = 17)\nend\nfor i in 1:n_diseases\n    text!(ax, disease_x[i] + 0.05, disease_y[i];\n          text = diseases[i], align = (:left, :center), color = INK, fontsize = 17)\nend\n\naxislegend(ax; position = :ct, orientation = :horizontal,\n           framevisible = false, labelcolor = INK, labelsize = 16,\n           padding = (0, 0, 0, 0))\n\n# --- Save -----------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}