{"spec_id":"heatmap-calendar","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nheatmap-calendar: Basic Calendar Heatmap\nLibrary: matplotlib 3.11.1 | Python 3.13.14\nQuality: 91/100 | Updated: 2026-07-23\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom matplotlib.colors import LinearSegmentedColormap\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Imprint sequential colormap (brand green -> blue) — identical across themes,\n# only chrome (background/text) adapts\ncmap = LinearSegmentedColormap.from_list(\"imprint_seq\", [\"#009E73\", \"#4467A3\"], N=256)\ncmap.set_bad(PAGE_BG)\n\n# Data\nnp.random.seed(42)\ndates = pd.date_range(start=\"2024-01-01\", end=\"2024-12-31\", freq=\"D\")\nn_days = len(dates)\ndate_idx = pd.DatetimeIndex(dates)\n\n# Vectorized activity generation with realistic developer patterns\nbase = np.random.poisson(3, n_days)\nweekday_mask = np.asarray(date_idx.dayofweek < 5)\nweekday_bonus = np.random.poisson(2, n_days) * weekday_mask\nzero_mask = np.random.random(n_days) < 0.15\nspike_mask = np.random.random(n_days) < 0.05\n\nactivity = (base + weekday_bonus).astype(float)\nactivity[zero_mask] = 0\nactivity += np.random.randint(0, 15, n_days) * spike_mask\n\n# Vacation period: 2 weeks of no activity in August\nvacation = np.asarray((date_idx.month == 8) & (date_idx.day >= 5) & (date_idx.day <= 19))\nactivity[vacation] = 0\n\n# Project deadline spike: high activity in late March\ndeadline = np.asarray((date_idx.month == 3) & (date_idx.day >= 20))\nactivity[deadline] += np.random.randint(5, 12, int(deadline.sum()))\n\n# Calendar layout — vectorized grid assignment\nweek_of_year = np.asarray((dates - dates[0]).days // 7)\ndayofweek = np.asarray(date_idx.dayofweek)\n\nn_weeks = week_of_year.max() + 1\nheatmap_data = np.full((7, n_weeks), np.nan)\nheatmap_data[dayofweek, week_of_year] = activity\n\n# Zero-activity days (vacation, off days) render as empty cells alongside\n# out-of-range grid padding, so the inactive stretch reads as a clear gap\n# rather than a low value on the imprint_seq scale\nplot_data = np.where(heatmap_data == 0, np.nan, heatmap_data)\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\nx = np.arange(n_weeks + 1)\ny = np.arange(8)\nmesh = ax.pcolormesh(\n    x,\n    y,\n    np.ma.masked_invalid(plot_data),\n    cmap=cmap,\n    vmin=np.nanmin(plot_data),\n    vmax=np.nanmax(plot_data),\n    edgecolors=PAGE_BG,\n    linewidth=1.5,\n)\n\n# Style: weekday labels on y-axis (kept well below the title's fontsize so the\n# title reads as the clear typographic anchor)\nweekday_labels = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"]\nax.set_yticks(np.arange(7) + 0.5)\nax.set_yticklabels(weekday_labels, fontsize=12, color=INK_SOFT)\n\n# Month labels at top\nmonth_positions = []\nmonth_labels = []\nfor month in range(1, 13):\n    mask = np.asarray(date_idx.month == month)\n    if mask.any():\n        month_positions.append(week_of_year[mask][0])\n        month_labels.append(pd.Timestamp(2024, month, 1).strftime(\"%b\"))\n\nax.set_xticks(month_positions)\nax.set_xticklabels(month_labels, fontsize=12, color=INK_SOFT)\nax.xaxis.tick_top()\nax.xaxis.set_label_position(\"top\")\n\nfor spine in ax.spines.values():\n    spine.set_visible(False)\n\nax.invert_yaxis()\nax.tick_params(colors=INK_SOFT, length=0)\n\n# Colorbar\ncbar = plt.colorbar(mesh, ax=ax, orientation=\"horizontal\", pad=0.05, shrink=0.55, aspect=35)\ncbar.ax.tick_params(labelsize=12, labelcolor=INK_SOFT, color=INK_SOFT)\ncbar.set_label(\"Daily Commits\", fontsize=12, color=INK_SOFT)\ncbar.outline.set_edgecolor(INK_SOFT)\n\nax.set_title(\"heatmap-calendar · python · matplotlib · anyplot.ai\", fontsize=18, fontweight=\"medium\", color=INK, pad=20)\n\n# Caption calling out the two visible narrative moments: the August vacation\n# gap and the late-March deadline spike\nplt.tight_layout(rect=(0, 0.05, 1, 1))\nfig.text(\n    0.5,\n    0.015,\n    \"Deadline crunch in late March, followed by a two-week vacation break in August\",\n    ha=\"center\",\n    va=\"bottom\",\n    fontsize=10,\n    color=INK_SOFT,\n    style=\"italic\",\n)\n\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}