{"spec_id":"heatmap-mandelbrot","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nheatmap-mandelbrot: Mandelbrot Set Fractal Visualization\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-30\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport seaborn as sns\nfrom matplotlib.colors import LinearSegmentedColormap\n\n\n# Theme tokens\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# Interior (never-escaping) points: near-black per spec, consistent across themes\nINTERIOR_BG = \"#0A0A08\"\n\n# Imprint sequential colormap — reversed so high iteration count (boundary) glows in brand green\nimprint_seq = LinearSegmentedColormap.from_list(\"imprint_seq\", [\"#4467A3\", \"#009E73\"])\n\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": INTERIOR_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Data — Mandelbrot set with smooth escape-time coloring\nx_min, x_max = -2.5, 1.0\ny_min, y_max = -1.25, 1.25\ngrid_w, grid_h = 1000, 714\nmax_iter = 200\nbailout = 256.0  # High bailout eliminates smooth-coloring artifacts\n\nreal = np.linspace(x_min, x_max, grid_w)\nimag = np.linspace(y_max, y_min, grid_h)\nc = real[np.newaxis, :] + 1j * imag[:, np.newaxis]\n\nz = np.zeros_like(c)\nescape_iter = np.full(c.shape, np.nan)\nescaped = np.zeros(c.shape, dtype=bool)\n\nfor i in range(1, max_iter + 1):\n    active = ~escaped\n    z[active] = z[active] ** 2 + c[active]\n    newly_escaped = active & (np.abs(z) > bailout)\n    if np.any(newly_escaped):\n        escaped[newly_escaped] = True\n        abs_z = np.abs(z[newly_escaped])\n        escape_iter[newly_escaped] = i + 1.0 - np.log2(np.log2(abs_z))\n\ninterior = ~escaped\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400)\nfig.set_facecolor(PAGE_BG)\n\nsns.heatmap(\n    escape_iter,\n    mask=interior,\n    cmap=imprint_seq,\n    vmin=1,\n    vmax=40,\n    cbar_kws={\"label\": \"Escape Iterations\", \"shrink\": 0.88, \"aspect\": 28, \"pad\": 0.02, \"format\": \"%.0f\"},\n    xticklabels=False,\n    yticklabels=False,\n    ax=ax,\n)\n\n# Custom axis ticks for complex plane coordinates\nn_xticks = 8\nn_yticks = 5\nax.set_xticks(np.linspace(0, grid_w, n_xticks))\nax.set_xticklabels([f\"{v:.1f}\" for v in np.linspace(x_min, x_max, n_xticks)], fontsize=8)\nax.set_yticks(np.linspace(0, grid_h, n_yticks))\nax.set_yticklabels([f\"{v:.1f}\" for v in np.linspace(y_max, y_min, n_yticks)], fontsize=8)\n\n# Labels and title — title is 50 chars, under the 67-char threshold so no scaling needed\ntitle = \"heatmap-mandelbrot · python · seaborn · anyplot.ai\"\nax.set_xlabel(\"Real Axis\", fontsize=10, labelpad=10)\nax.set_ylabel(\"Imaginary Axis\", fontsize=10, labelpad=10)\nax.set_title(title, fontsize=12, fontweight=\"medium\", pad=14)\n\n# Colorbar styling\ncbar = ax.collections[0].colorbar\ncbar.ax.tick_params(labelsize=8, colors=INK_SOFT)\ncbar.set_label(\"Escape Iterations\", fontsize=10, labelpad=10, color=INK)\ncbar.outline.set_edgecolor(INK_SOFT)\ncbar.outline.set_linewidth(0.5)\n\nsns.despine(ax=ax, left=True, bottom=True)\n\nfig.subplots_adjust(left=0.09, right=0.89, top=0.92, bottom=0.11)\n\n# Save — no bbox_inches='tight' (would trim canvas from exact 3200×1800)\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}