{"spec_id":"heatmap-polar","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nheatmap-polar: Polar Heatmap for Cyclic Two-Dimensional Data\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 85/100 | Created: 2026-05-13\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport seaborn as sns\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\"\n\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.10,\n    },\n)\n\n# Data: hourly website traffic by day of week\nnp.random.seed(42)\ndays = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"]\nn_days = len(days)\nn_hours = 24\n\n# Synthetic traffic with realistic weekday/weekend patterns\ntraffic = np.zeros((n_days, n_hours))\nfor d in range(n_days):\n    for h in range(n_hours):\n        if d >= 5:  # Weekend: afternoon peak\n            traffic[d, h] = 200 + 400 * np.exp(-0.5 * ((h - 14) / 4) ** 2)\n        else:  # Weekday: morning and afternoon peaks\n            morning = 300 * np.exp(-0.5 * ((h - 9) / 2) ** 2)\n            afternoon = 500 * np.exp(-0.5 * ((h - 15) / 2.5) ** 2)\n            traffic[d, h] = 150 + morning + afternoon\ntraffic += np.random.normal(0, 20, traffic.shape)\ntraffic = np.clip(traffic, 0, None)\n\n# Plot — polar projection for the circular heatmap\nfig = plt.figure(figsize=(12, 12), facecolor=PAGE_BG)\nax = fig.add_subplot(111, projection=\"polar\")\nax.set_facecolor(PAGE_BG)\n\ntheta_edges = np.linspace(0, 2 * np.pi, n_hours + 1)\nr_edges = np.arange(n_days + 1, dtype=float)\n\nmesh = ax.pcolormesh(theta_edges, r_edges, traffic, cmap=\"viridis\", shading=\"flat\")\n\n# Clock orientation: midnight at top, clockwise like a 24-hour clock face\nax.set_theta_zero_location(\"N\")\nax.set_theta_direction(-1)\n\n# Hour labels at the four cardinal positions only\nhour_positions = np.linspace(0, 2 * np.pi, n_hours, endpoint=False)\nax.set_xticks(hour_positions)\nhour_labels = [\n    \"12am\" if h == 0 else \"6am\" if h == 6 else \"12pm\" if h == 12 else \"6pm\" if h == 18 else \"\" for h in range(n_hours)\n]\nax.set_xticklabels(hour_labels, fontsize=18, color=INK_SOFT, fontweight=\"medium\")\n\n# Day-of-week labels at the center of each radial ring\nax.set_yticks(np.arange(n_days) + 0.5)\nax.set_yticklabels(days, fontsize=16, color=INK_SOFT)\nax.set_ylim(0, n_days)\nax.tick_params(axis=\"y\", length=0)\n\n# Subtle cell gridlines to separate rings and sectors\nax.grid(True, alpha=0.12, color=INK, linewidth=0.6)\n\n# Colorbar legend\ncbar = plt.colorbar(mesh, ax=ax, pad=0.13, fraction=0.03, aspect=30)\ncbar.set_label(\"Hourly Visits\", fontsize=20, color=INK)\ncbar.ax.tick_params(labelsize=16, colors=INK_SOFT)\nplt.setp(cbar.ax.yaxis.get_ticklabels(), color=INK_SOFT)\ncbar.outline.set_edgecolor(INK_SOFT)\n\nax.set_title(\n    \"Website Traffic · heatmap-polar · seaborn · anyplot.ai\", fontsize=24, fontweight=\"medium\", color=INK, pad=25\n)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}