{"spec_id":"heatmap-calendar","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nheatmap-calendar: Basic Calendar Heatmap\nLibrary: plotnine 0.15.7 | Python 3.13.14\nQuality: 93/100 | Updated: 2026-07-23\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_blank,\n    element_rect,\n    element_text,\n    geom_text,\n    geom_tile,\n    ggplot,\n    ggsave,\n    labs,\n    scale_fill_gradient,\n    scale_x_continuous,\n    scale_y_discrete,\n    theme,\n    theme_minimal,\n)\n\n\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\"\nIMPRINT_PALETTE = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\n\n# Data - One year of daily activity (GitHub-style contribution data)\nnp.random.seed(42)\n\nstart_date = pd.Timestamp(\"2024-01-01\")\nend_date = pd.Timestamp(\"2024-12-31\")\ndates = pd.date_range(start=start_date, end=end_date, freq=\"D\")\n\nvalues = []\nfor date in dates:\n    base = np.random.poisson(5)\n    if date.dayofweek >= 5:\n        base = int(base * 0.3)\n    if date.month in [3, 4, 9, 10]:\n        base = int(base * 1.5)\n    if date.month in [7, 8]:\n        base = int(base * 0.5)\n    if np.random.random() < 0.15:\n        base = 0\n    values.append(max(0, base))\n\ndf = pd.DataFrame({\"date\": dates, \"value\": values})\n\ndf[\"week\"] = df[\"date\"].dt.isocalendar().week\ndf[\"day_of_week\"] = df[\"date\"].dt.dayofweek\ndf[\"month\"] = df[\"date\"].dt.month\n\ndf[\"week_adjusted\"] = df[\"week\"].astype(int)\nmask = (df[\"month\"] == 1) & (df[\"week\"] > 50)\ndf.loc[mask, \"week_adjusted\"] = 0\nmask = (df[\"month\"] == 12) & (df[\"week\"] == 1)\ndf.loc[mask, \"week_adjusted\"] = 53\n\nweekday_labels = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"]\ndf[\"weekday\"] = df[\"day_of_week\"].map(lambda x: weekday_labels[x])\ndf[\"weekday\"] = pd.Categorical(df[\"weekday\"], categories=weekday_labels[::-1], ordered=True)\n\n# Zero-activity days rendered as NA so they blend with the panel background\ndf[\"value_display\"] = df[\"value\"].where(df[\"value\"] > 0, other=None)\n\n# Month labels are placed as text above the top row (spec asks for \"top or\n# section headers\") instead of on a conventional bottom x-axis.\nmonth_labels = df.groupby(\"month\")[\"week_adjusted\"].min().reset_index()\nmonth_names = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\nmonth_labels[\"month_name\"] = month_labels[\"month\"].map(lambda x: month_names[x - 1])\nmonth_labels[\"top_row\"] = weekday_labels[0]\n\nplot = (\n    ggplot(df, aes(x=\"week_adjusted\", y=\"weekday\", fill=\"value_display\"))\n    + geom_tile(color=PAGE_BG, size=0.4)\n    + geom_text(\n        month_labels,\n        aes(x=\"week_adjusted\", y=\"top_row\", label=\"month_name\"),\n        inherit_aes=False,\n        nudge_y=0.9,\n        ha=\"left\",\n        va=\"bottom\",\n        size=8,\n        color=INK_SOFT,\n    )\n    + scale_fill_gradient(low=IMPRINT_PALETTE[0], high=IMPRINT_PALETTE[2], na_value=PAGE_BG, name=\"Contributions\")\n    + scale_x_continuous(breaks=[], expand=(0, 0.5, 0, 2))\n    + scale_y_discrete(expand=(0, 0.6, 0, 1))\n    + labs(x=\"\", y=\"\", title=\"heatmap-calendar · python · plotnine · anyplot.ai\")\n    + theme_minimal()\n    + theme(\n        figure_size=(8, 4.5),\n        text=element_text(size=7, color=INK_SOFT),\n        axis_title=element_blank(),\n        axis_text_x=element_blank(),\n        axis_ticks_major_x=element_blank(),\n        axis_text_y=element_text(size=9, color=INK_SOFT),\n        plot_title=element_text(size=12, weight=\"bold\", color=INK),\n        legend_title=element_text(size=9, color=INK),\n        legend_text=element_text(size=8, color=INK_SOFT),\n        panel_grid_major=element_blank(),\n        panel_grid_minor=element_blank(),\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        legend_background=element_rect(fill=ELEVATED_BG, color=ELEVATED_BG),\n        legend_frame=element_blank(),\n    )\n)\n\nggsave(plot, filename=f\"plot-{THEME}.png\", dpi=400, width=8, height=4.5, units=\"in\", verbose=False)\n"}