{"spec_id":"contour-density","library":"makie","language":"julia","code":"# anyplot.ai\n# contour-density: Density Contour Plot\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 89/100 | Created: 2026-09-04\n\nusing CairoMakie\nusing Colors\nusing RDatasets\nusing Statistics\n\n# --- Theme tokens -----------------------------------------------------------\nTHEME    = get(ENV, \"ANYPLOT_THEME\", \"light\")\nPAGE_BG  = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nINK      = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nINK_SOFT = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\n\n# Imprint sequential colormap — density is single-polarity (concentration only)\nANYPLOT_SEQ = cgrad([colorant\"#009E73\", colorant\"#4467A3\"])\n\n# Fixed (non-theme-flipping) ink for annotations placed on top of the density\n# fill: the fill's colors are identical in both themes, and dark-on-fill\n# measures ~5:1 contrast vs. ~3:1 for light-on-fill, so unlike the chrome,\n# this text should NOT flip with THEME.\nANNOTATION_INK  = colorant\"#1A1A17\"\nANNOTATION_HALO = colorant\"#FAF8F1\"\n\n# --- Data ---------------------------------------------------------------\n# Old Faithful geyser: eruption duration vs. waiting time until next eruption.\n# The classic bimodal bivariate dataset for demonstrating density contours.\nfaithful = RDatasets.dataset(\"datasets\", \"faithful\")\nduration = Float64.(faithful.Eruptions)\nwaiting  = Float64.(faithful.Waiting)\nn        = length(duration)\n\n# 2D Gaussian KDE evaluated on a regular grid, bandwidth via Silverman's rule.\npad_x  = 0.15 * (maximum(duration) - minimum(duration))\npad_y  = 0.15 * (maximum(waiting) - minimum(waiting))\nxgrid  = range(minimum(duration) - pad_x, maximum(duration) + pad_x; length=150)\nygrid  = range(minimum(waiting) - pad_y, maximum(waiting) + pad_y; length=150)\n\nbw_x = std(duration) * n^(-1 / 6)\nbw_y = std(waiting) * n^(-1 / 6)\n\ndensity = [\n    sum(\n        exp(-0.5 * (((xi - duration[k]) / bw_x)^2 + ((yi - waiting[k]) / bw_y)^2))\n        for k in 1:n\n    )\n    for xi in xgrid, yi in ygrid\n] ./ (n * 2π * bw_x * bw_y)\n\n# --- Plot -----------------------------------------------------------------\nfig = Figure(\n    resolution      = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"Old Faithful Geyser · contour-density · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Eruption Duration (min)\",\n    ylabel             = \"Waiting Time to Next Eruption (min)\",\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)\n\ncf = contourf!(ax, xgrid, ygrid, density; levels=10, colormap=ANYPLOT_SEQ)\ncontour!(ax, xgrid, ygrid, density; levels=10, color=(PAGE_BG, 0.35), linewidth=1)\nscatter!(\n    ax, duration, waiting;\n    color       = (INK, 0.35),\n    markersize  = 6,\n    strokewidth = 0.5,\n    strokecolor = (PAGE_BG, 0.6),\n)\n\n# Callouts for Old Faithful's two well-known eruption regimes, placed in the\n# low-density (green) margin above/below each cluster.\ntext!(\n    ax, 2.0, 40;\n    text        = \"Short eruptions\",\n    color       = ANNOTATION_INK,\n    fontsize    = 13,\n    strokecolor = (ANNOTATION_HALO, 0.6),\n    strokewidth = 1,\n    align       = (:center, :center),\n)\ntext!(\n    ax, 4.3, 100;\n    text        = \"Long eruptions\",\n    color       = ANNOTATION_INK,\n    fontsize    = 13,\n    strokecolor = (ANNOTATION_HALO, 0.6),\n    strokewidth = 1,\n    align       = (:center, :center),\n)\n\nColorbar(\n    fig[1, 2], cf;\n    label           = \"Density\",\n    labelsize       = 14,\n    labelcolor      = INK,\n    ticklabelsize   = 12,\n    ticklabelcolor  = INK_SOFT,\n    tickcolor       = INK_SOFT,\n)\n\ncolsize!(fig.layout, 1, Relative(0.88))\n\n# --- Save -------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}