{"spec_id":"recurrence-basic","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nrecurrence-basic: Recurrence Plot for Nonlinear Time Series\nLibrary: plotnine 0.15.5 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-06-10\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    annotate,\n    coord_equal,\n    element_blank,\n    element_line,\n    element_rect,\n    element_text,\n    geom_tile,\n    ggplot,\n    guide_colorbar,\n    guides,\n    labs,\n    scale_fill_gradient,\n    scale_x_continuous,\n    scale_y_continuous,\n    theme,\n    theme_minimal,\n)\nfrom scipy.spatial.distance import cdist\n\n\n# Theme tokens — Imprint palette, theme-adaptive chrome\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Data — Logistic map near onset of chaos (r=3.82)\nnp.random.seed(42)\nn_steps = 200\nr = 3.82\nx = np.zeros(n_steps)\nx[0] = 0.1\nfor i in range(1, n_steps):\n    x[i] = r * x[i - 1] * (1 - x[i - 1])\n\n# Time-delay embedding (dimension=3, delay=2) — wider delay reveals more structure\nembedding_dim = 3\ndelay = 2\nn_embedded = n_steps - (embedding_dim - 1) * delay\nembedded = np.array([x[i * delay : i * delay + n_embedded] for i in range(embedding_dim)]).T\n\n# Distance matrix (Euclidean distance in embedding space) and proximity for color mapping\ndistance_matrix = cdist(embedded, embedded, metric=\"euclidean\")\nthreshold = 0.12\n\nrow_idx, col_idx = np.where(distance_matrix < threshold)\ndistances = distance_matrix[row_idx, col_idx]\nproximity = 1.0 - distances / threshold\n\ndf = pd.DataFrame({\"Time_i\": row_idx, \"Time_j\": col_idx, \"Proximity\": proximity})\n\n# Laminar region (vertical/horizontal clusters near t=118-152)\nlaminar_start, laminar_end = 118, 152\n\n# Plot — color-mapped recurrence plot with Imprint sequential colormap (imprint_seq)\nplot = (\n    ggplot(df, aes(x=\"Time_i\", y=\"Time_j\", fill=\"Proximity\"))\n    + geom_tile(width=1.1, height=1.1)\n    + scale_fill_gradient(\n        low=\"#009E73\",\n        high=\"#4467A3\",\n        name=\"Recurrence\\nStrength\",\n        limits=(0, 1),\n        breaks=[0.0, 0.5, 1.0],\n        labels=[\"Weak\", \"Medium\", \"Strong\"],\n    )\n    + guides(fill=guide_colorbar(nbin=200))\n    + annotate(\n        \"rect\",\n        xmin=laminar_start,\n        xmax=laminar_end,\n        ymin=laminar_start,\n        ymax=laminar_end,\n        fill=\"none\",\n        color=\"#AE3030\",\n        size=1.2,\n        linetype=\"dashed\",\n    )\n    + annotate(\n        \"text\",\n        x=laminar_end + 5,\n        y=laminar_end + 5,\n        label=\"Laminar\\nregime\",\n        ha=\"left\",\n        va=\"bottom\",\n        size=3.5,\n        color=\"#AE3030\",\n        fontstyle=\"italic\",\n    )\n    + scale_x_continuous(\n        name=\"Time Index  (Logistic Map, r = 3.82)\", expand=(0.01, 0), breaks=range(0, n_embedded + 1, 40)\n    )\n    + scale_y_continuous(\n        name=\"Time Index  (Logistic Map, r = 3.82)\", expand=(0.01, 0), breaks=range(0, n_embedded + 1, 40)\n    )\n    + coord_equal(ratio=1)\n    + labs(\n        title=\"recurrence-basic · python · plotnine · anyplot.ai\",\n        subtitle=\"Diagonal lines → determinism  ·  Dense blocks → regime changes\",\n    )\n    + theme_minimal(base_size=8, base_family=\"sans-serif\")\n    + theme(\n        figure_size=(6, 6),\n        text=element_text(color=INK),\n        plot_title=element_text(size=12, ha=\"center\", weight=\"bold\", margin={\"b\": 4}),\n        plot_subtitle=element_text(size=9, ha=\"center\", color=INK_SOFT, margin={\"b\": 10}),\n        axis_title_x=element_text(size=10, margin={\"t\": 8}),\n        axis_title_y=element_text(size=10, margin={\"r\": 8}),\n        axis_text_x=element_text(size=8, color=INK_SOFT),\n        axis_text_y=element_text(size=8, color=INK_SOFT),\n        axis_ticks_major=element_line(color=INK_SOFT, size=0.4),\n        axis_ticks_length=3,\n        legend_title=element_text(size=8, weight=\"bold\", color=INK),\n        legend_text=element_text(size=7, color=INK_SOFT),\n        legend_position=\"right\",\n        legend_background=element_rect(fill=ELEVATED_BG, color=\"none\"),\n        panel_grid_major=element_blank(),\n        panel_grid_minor=element_blank(),\n        panel_background=element_rect(fill=PAGE_BG),\n        panel_border=element_rect(color=INK_SOFT, fill=None, size=0.3),\n        plot_background=element_rect(fill=PAGE_BG, color=\"none\"),\n    )\n)\n\nplot.save(f\"plot-{THEME}.png\", dpi=400, width=6, height=6, units=\"in\", verbose=False)\n"}