{"spec_id":"scatter-hr-diagram","library":"makie","language":"julia","code":"# anyplot.ai\n# scatter-hr-diagram: Hertzsprung-Russell Diagram\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 84/100 | Created: 2026-06-02\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\"\n\n# Imprint palette — 8 hues, hybrid-v3 sort, theme-independent\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\",  # 1 — brand green (first series)\n    colorant\"#C475FD\",  # 2 — lavender\n    colorant\"#4467A3\",  # 3 — blue\n    colorant\"#BD8233\",  # 4 — ochre\n    colorant\"#AE3030\",  # 5 — matte red\n    colorant\"#2ABCCD\",  # 6 — cyan\n    colorant\"#954477\",  # 7 — rose\n    colorant\"#99B314\",  # 8 — lime\n]\n\n# Spectral type color assignments — G first so brand green (#009E73) leads the legend.\n# Colors approximate the conventional O(blue)→M(red) spectral temperature sequence.\nconst SPECTRAL_ORDER = [\"G\", \"K\", \"M\", \"F\", \"A\", \"B\", \"O\"]\nconst SPECTRAL_COLORS = Dict{String, typeof(IMPRINT_PALETTE[1])}(\n    \"G\" => IMPRINT_PALETTE[1],   # #009E73 brand green  (G-type solar, most recognisable)\n    \"K\" => IMPRINT_PALETTE[4],   # #BD8233 ochre        (K-type orange)\n    \"M\" => IMPRINT_PALETTE[5],   # #AE3030 matte red    (M-type conventional red)\n    \"F\" => IMPRINT_PALETTE[8],   # #99B314 lime         (F-type yellow-white)\n    \"A\" => IMPRINT_PALETTE[2],   # #C475FD lavender     (A-type white)\n    \"B\" => IMPRINT_PALETTE[6],   # #2ABCCD cyan         (B-type blue-white)\n    \"O\" => IMPRINT_PALETTE[3],   # #4467A3 blue         (O-type conventional deep blue)\n)\n\n# Assign spectral type by surface temperature (standard Harvard classification)\nfunction spectral_type(T::Float64)\n    T < 3700  && return \"M\"\n    T < 5200  && return \"K\"\n    T < 6000  && return \"G\"\n    T < 7500  && return \"F\"\n    T < 10000 && return \"A\"\n    T < 30000 && return \"B\"\n    return \"O\"\nend\n\n# Data — synthetic stellar populations for HR diagram\nn_ms = 200\nms_temp = exp.(range(log(3200.0), log(38000.0), length=n_ms) .+ randn(n_ms) .* 0.06)\nms_lum  = (ms_temp ./ 5778.0) .^ 3.5 .* exp.(randn(n_ms) .* 0.22)\n\nn_rg = 45\nrg_temp = exp.(log(3900.0) .+ randn(n_rg) .* 0.16)\nrg_lum  = exp.(range(log(10.0), log(600.0), length=n_rg) .+ randn(n_rg) .* 0.35)\n\nn_sg = 18\nsg_temp = exp.(range(log(3500.0), log(22000.0), length=n_sg) .+ randn(n_sg) .* 0.18)\nsg_lum  = exp.(range(log(4000.0), log(180000.0), length=n_sg) .+ randn(n_sg) .* 0.30)\n\nn_wd = 28\nwd_temp = exp.(range(log(9000.0), log(55000.0), length=n_wd) .+ randn(n_wd) .* 0.12)\nwd_lum  = exp.(range(log(0.0001), log(0.008), length=n_wd) .+ randn(n_wd) .* 0.30)\n\n# Merge all populations; assign spectral types by temperature\nall_temp  = vcat(ms_temp, rg_temp, sg_temp, wd_temp)\nall_lum   = vcat(ms_lum,  rg_lum,  sg_lum,  wd_lum)\nall_stype = spectral_type.(all_temp)\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              = \"scatter-hr-diagram · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Surface Temperature (K)\",\n    ylabel             = \"Luminosity (L☉)\",\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,                  # y-only grid reduces clutter on scatter\n    ygridcolor         = RGBAf(Float32(INK.r), Float32(INK.g), Float32(INK.b), 0.12f0),\n    xscale             = log10,\n    yscale             = log10,\n    xreversed          = true,\n    xticks             = ([3000, 5000, 10000, 20000, 40000],\n                          [\"3k\", \"5k\", \"10k\", \"20k\", \"40k\"]),\n)\n\n# Faint main-sequence reference spine highlights the diagonal trend\nms_T_spine = collect(range(3000.0, 40000.0, length=120))\nms_L_spine = (ms_T_spine ./ 5778.0) .^ 3.5\nlines!(ax, ms_T_spine, ms_L_spine;\n    color = (INK_SOFT, 0.30), linewidth = 1.5, linestyle = :dash)\n\n# Scatter by spectral type — G first so brand green leads as first series\nfor stype in SPECTRAL_ORDER\n    idx = findall(==(stype), all_stype)\n    isempty(idx) && continue\n    scatter!(ax, all_temp[idx], all_lum[idx];\n        color       = (SPECTRAL_COLORS[stype], 0.70),\n        markersize  = 8,\n        strokewidth = 0,\n        label       = stype * \"-type\")\nend\n\n# Sun reference — G2V, gold star5 marker\nscatter!(ax, [5778.0], [1.0];\n    color       = colorant\"#DDCC77\",\n    markersize  = 20,\n    marker      = :star5,\n    strokewidth = 1.5,\n    strokecolor = INK,\n    label       = \"Sun (G2V)\")\n\n# Region labels — placed in whitespace away from dense populations\ntext!(ax, 7000.0, 25.0;\n    text = \"Main Sequence\", fontsize = 12, color = INK_SOFT, align = (:center, :center))\ntext!(ax, 3750.0, 200.0;\n    text = \"Red Giants\",    fontsize = 12, color = INK_SOFT, align = (:center, :center))\ntext!(ax, 10000.0, 80000.0;\n    text = \"Supergiants\",   fontsize = 12, color = INK_SOFT, align = (:center, :center))\ntext!(ax, 25000.0, 0.002;\n    text = \"White Dwarfs\",  fontsize = 12, color = INK_SOFT, align = (:center, :center))\n\n# Legend\naxislegend(ax;\n    position        = :rb,\n    backgroundcolor = ELEVATED_BG,\n    framecolor      = INK_SOFT,\n    fontsize        = 10,\n)\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}