{"spec_id":"recurrence-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# recurrence-basic: Recurrence Plot for Nonlinear Time Series\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 89/100 | Created: 2026-06-10\n\nusing CairoMakie\nusing Colors\nusing ColorSchemes\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]\n\n# Data — Lorenz attractor x-component via Euler integration\ndt = 0.01\nsigma, rho, beta = 10.0, 28.0, 8.0 / 3.0\nn_steps = 3000\nlx, ly, lz = zeros(n_steps), zeros(n_steps), zeros(n_steps)\nlx[1], ly[1], lz[1] = 1.0, 0.0, 0.0\nfor i in 2:n_steps\n    lx[i] = lx[i-1] + dt * sigma * (ly[i-1] - lx[i-1])\n    ly[i] = ly[i-1] + dt * (lx[i-1] * (rho - lz[i-1]) - ly[i-1])\n    lz[i] = lz[i-1] + dt * (lx[i-1] * ly[i-1] - beta * lz[i-1])\nend\n\n# Extract 500 steps after transient; use all three state variables for embedding\nts_x = lx[1501:2000]\nts_y = ly[1501:2000]\nts_z = lz[1501:2000]\nn = length(ts_x)\n\n# Pairwise Euclidean distance in full 3D Lorenz state space\ndist = zeros(Float32, n, n)\nfor i in 1:n\n    for j in 1:n\n        dist[i, j] = sqrt(\n            (ts_x[i] - ts_x[j])^2 +\n            (ts_y[i] - ts_y[j])^2 +\n            (ts_z[i] - ts_z[j])^2\n        )\n    end\nend\n\n# Threshold at the 10th percentile → ~10% recurrence rate\nsorted_dist = sort(vec(dist))\nepsilon = sorted_dist[round(Int, 0.10 * length(sorted_dist))]\nrecurrence = Float32.(dist .<= epsilon)\n\n# Colormap: non-recurrent → background, recurrent → Imprint brand green\ncmap = cgrad([PAGE_BG, IMPRINT_PALETTE[1]])\n\n# Plot — square canvas for symmetric recurrence matrix\nfig = Figure(\n    size            = (1200, 1200),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"recurrence-basic · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Time Index\",\n    ylabel             = \"Time Index\",\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,\n    ygridvisible       = false,\n    aspect             = DataAspect(),\n)\n\nheatmap!(ax, 1:n, 1:n, recurrence; colormap = cmap, colorrange = (0.0f0, 1.0f0))\n\n# Annotation: guide the viewer to the key structural insight\ntext!(ax, 10.0, 490.0;\n    text = \"Diagonal lines\\n= determinism\",\n    color = INK_SOFT, fontsize = 11,\n    align = (:left, :top))\narrows!(ax, [90.0], [450.0], [90.0], [-90.0];\n    color = INK_SOFT, linewidth = 1.0, arrowsize = 10.0)\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}