{"spec_id":"heatmap-polar","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nheatmap-polar: Polar Heatmap for Cyclic Two-Dimensional Data\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 90/100 | Created: 2026-05-13\n\"\"\"\n\nimport os\nimport sys\n\n\nsys.path.pop(0)  # prevent shadowing the matplotlib library with this file\n\nimport matplotlib.pyplot as plt\nimport numpy as np\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# Data — hourly website visits by day of week\nnp.random.seed(42)\ndays = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"]\nn_days = 7\nn_hours = 24\nh = np.arange(n_hours, dtype=float)\n\n# Weekday pattern: morning surge (9am) + evening surge (7pm) + late-night tail\nwd_factors = [0.92, 0.98, 1.05, 1.02, 1.08]\ntraffic = np.zeros((n_days, n_hours))\nfor i in range(5):\n    f = wd_factors[i]\n    base = (\n        700 * np.exp(-0.5 * ((h - 9) / 1.5) ** 2)\n        + 800 * np.exp(-0.5 * ((h - 19) / 2.0) ** 2)\n        + 90 * np.exp(-0.5 * ((h - 3) / 2.5) ** 2)\n    )\n    traffic[i] = np.maximum(50, base * f + np.random.normal(0, 25, n_hours))\n\n# Weekend pattern: broad afternoon peak (2pm), quieter mornings\nfor i in range(5, 7):\n    base = 850 * np.exp(-0.5 * ((h - 14) / 3.5) ** 2) + 70 * np.exp(-0.5 * ((h - 2) / 2.0) ** 2)\n    traffic[i] = np.maximum(50, base + np.random.normal(0, 25, n_hours))\n\n# Plot\nfig = plt.figure(figsize=(12, 12), facecolor=PAGE_BG)\nax = fig.add_subplot(111, projection=\"polar\")\nax.set_facecolor(PAGE_BG)\n\n# Clock orientation: midnight at top, hours run clockwise\nax.set_theta_zero_location(\"N\")\nax.set_theta_direction(-1)\n\nr_inner, r_outer = 2.0, 9.0\ntheta_edges = np.linspace(0, 2 * np.pi, n_hours + 1)  # 25 edges for 24 hour cells\nr_edges = np.linspace(r_inner, r_outer, n_days + 1)  # 8 edges for 7 day rings\nr_centers = (r_edges[:-1] + r_edges[1:]) / 2\n\nmesh = ax.pcolormesh(theta_edges, r_edges, traffic, cmap=\"viridis\", shading=\"flat\")\n\n# Cell borders — background-colored lines separate angular and radial cells\ncircle_theta = np.linspace(0, 2 * np.pi, 300)\nfor r in r_edges:\n    ax.plot(circle_theta, [r] * 300, color=PAGE_BG, linewidth=1.2, zorder=5)\nfor theta in theta_edges:\n    ax.plot([theta, theta], [r_inner, r_outer], color=PAGE_BG, linewidth=0.7, zorder=5)\n\n# Angular axis: label at clock quadrants only\nax.set_xticks([0, np.pi / 2, np.pi, 3 * np.pi / 2])\nax.set_xticklabels([\"12am\", \"6am\", \"12pm\", \"6pm\"], fontsize=18, color=INK_SOFT)\nax.tick_params(axis=\"x\", pad=15, colors=INK_SOFT)\n\n# Radial axis: day-of-week labels with background box for contrast against dark viridis cells\nax.set_yticks([])\nax.set_yticklabels([])\nax.set_ylim(0, r_outer + 0.3)\nlabel_angle = 2 * np.pi * 1.5 / 24  # 1:30am clockwise from midnight\nfor r, day in zip(r_centers, days, strict=False):\n    ax.text(\n        label_angle,\n        r,\n        day,\n        ha=\"center\",\n        va=\"center\",\n        fontsize=14,\n        color=INK,\n        fontweight=\"medium\",\n        zorder=10,\n        bbox={\n            \"facecolor\": ELEVATED_BG,\n            \"edgecolor\": INK_SOFT,\n            \"alpha\": 0.88,\n            \"boxstyle\": \"round,pad=0.25\",\n            \"linewidth\": 0.5,\n        },\n    )\n\nax.grid(False)\nax.spines[\"polar\"].set_visible(False)\n\n# Title\nax.set_title(\n    \"Website Traffic · heatmap-polar · matplotlib · anyplot.ai\", fontsize=22, fontweight=\"medium\", color=INK, pad=30\n)\n\n# Colorbar\ncbar = fig.colorbar(mesh, ax=ax, fraction=0.04, pad=0.1, shrink=0.72, aspect=22)\ncbar.set_label(\"Hourly Visits\", fontsize=18, color=INK)\ncbar.ax.tick_params(labelsize=14, labelcolor=INK_SOFT, color=INK_SOFT)\ncbar.outline.set_edgecolor(INK_SOFT)\n\n# Save\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}