{"spec_id":"bifurcation-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nbifurcation-basic: Bifurcation Diagram for Dynamical Systems\nLibrary: matplotlib 3.11.0 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-06-17\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.colors import LinearSegmentedColormap, PowerNorm\n\n\n# 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\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Continuous density → Imprint sequential cmap (brand green → blue).\n# Empty bins render as the page background so the diagram floats on the surface.\nimprint_seq = LinearSegmentedColormap.from_list(\"imprint_seq\", [\"#009E73\", \"#4467A3\"])\nimprint_seq.set_bad(PAGE_BG)\n\n# Data — logistic map x(n+1) = r * x(n) * (1 - x(n))\nr_min, r_max = 2.5, 4.0\nnum_r = 2000\ntransient = 200\niterations = 100\n\nr_values = np.linspace(r_min, r_max, num_r)\nr_plot = np.empty(num_r * iterations)\nx_plot = np.empty(num_r * iterations)\n\nfor i, r in enumerate(r_values):\n    x = 0.5\n    for _ in range(transient):\n        x = r * x * (1 - x)\n    for j in range(iterations):\n        x = r * x * (1 - x)\n        r_plot[i * iterations + j] = r\n        x_plot[i * iterations + j] = x\n\n# 2D histogram for density-based rendering of the attractor structure.\n# Reveals periodic windows within chaos far better than a raw scatter.\nr_bins = 800\nx_bins = 600\nhist, r_edges, x_edges = np.histogram2d(r_plot, x_plot, bins=[r_bins, x_bins], range=[[r_min, r_max], [0, 1]])\nhist = np.ma.masked_where(hist == 0, hist)\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Density heatmap; PowerNorm lifts low-density branches into visibility.\nax.pcolormesh(\n    r_edges,\n    x_edges,\n    hist.T,\n    cmap=imprint_seq,\n    norm=PowerNorm(gamma=0.40, vmin=1, vmax=hist.max()),\n    rasterized=True,\n    zorder=1,\n)\n\n# Regime labels at the bottom carry the stability → chaos narrative.\nlabel_bbox = {\"boxstyle\": \"round,pad=0.3\", \"facecolor\": ELEVATED_BG, \"edgecolor\": \"none\", \"alpha\": 0.85}\nfor rx, label in [(2.75, \"Stable\"), (3.28, \"Periodic\"), (3.78, \"Chaotic\")]:\n    ax.text(\n        rx,\n        0.04,\n        label,\n        transform=ax.get_xaxis_transform(),\n        fontsize=9,\n        color=INK_MUTED,\n        ha=\"center\",\n        va=\"bottom\",\n        fontstyle=\"italic\",\n        bbox=label_bbox,\n        zorder=3,\n    )\n\n# Key period-doubling bifurcations — dashed markers with spaced callouts.\nann_bbox = {\"boxstyle\": \"round,pad=0.3\", \"facecolor\": ELEVATED_BG, \"edgecolor\": INK_SOFT, \"alpha\": 0.9}\nbifurcation_points = [(3.0, \"Period-2\", -10, 0.97), (3.449, \"Period-4\", -10, 0.97), (3.544, \"Period-8\", -10, 0.87)]\nfor r_bif, label, x_offset, y_frac in bifurcation_points:\n    ax.axvline(r_bif, color=INK_SOFT, linewidth=0.7, linestyle=\"--\", alpha=0.45, zorder=2)\n    ax.annotate(\n        f\"{label}  r ≈ {r_bif}\",\n        xy=(r_bif, y_frac),\n        xycoords=(\"data\", \"axes fraction\"),\n        xytext=(x_offset, 0),\n        textcoords=\"offset points\",\n        fontsize=9,\n        color=INK,\n        ha=\"right\",\n        va=\"top\",\n        bbox=ann_bbox,\n        zorder=4,\n    )\n\n# Onset of chaos\nax.annotate(\n    \"Onset of chaos\\nr ≈ 3.57\",\n    xy=(3.57, 0.75),\n    xytext=(3.75, 0.93),\n    fontsize=9,\n    color=INK,\n    ha=\"center\",\n    bbox=ann_bbox,\n    arrowprops={\"arrowstyle\": \"->\", \"color\": INK_SOFT, \"connectionstyle\": \"arc3,rad=-0.2\"},\n    zorder=4,\n)\n\n# Style\nax.set_xlabel(\"Growth Rate (r)\", fontsize=10, color=INK)\nax.set_ylabel(\"Steady-State Population (x)\", fontsize=10, color=INK)\ntitle = \"bifurcation-basic · python · matplotlib · anyplot.ai\"\nax.set_title(title, fontsize=12, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT, labelcolor=INK_SOFT)\nax.set_xlim(r_min, r_max)\nax.set_ylim(0, 1)\nfor s in (\"left\", \"bottom\"):\n    ax.spines[s].set_color(INK_SOFT)\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\n\nfig.subplots_adjust(left=0.07, right=0.97, top=0.92, bottom=0.10)\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}