{"spec_id":"heatmap-geographic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nheatmap-geographic: Geographic Heatmap for Spatial Density\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 83/100 | Updated: 2026-05-19\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\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_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        \"grid.color\": INK,\n        \"grid.alpha\": 0.10,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Data: Mobile app check-in density across central Tokyo districts\nnp.random.seed(42)\n\n# Shinjuku — major rail hub and entertainment district\nshinjuku_lat = np.random.normal(35.690, 0.012, 280)\nshinjuku_lon = np.random.normal(139.700, 0.012, 280)\n\n# Shibuya — commercial and youth culture centre\nshibuya_lat = np.random.normal(35.660, 0.010, 220)\nshibuya_lon = np.random.normal(139.699, 0.010, 220)\n\n# Ginza — luxury retail and business district\nginza_lat = np.random.normal(35.672, 0.008, 180)\nginza_lon = np.random.normal(139.763, 0.008, 180)\n\n# Akihabara — electronics and pop-culture district\nakiba_lat = np.random.normal(35.700, 0.007, 140)\nakiba_lon = np.random.normal(139.773, 0.007, 140)\n\n# Scattered activity across central Tokyo\nscattered_lat = np.random.uniform(35.63, 35.73, 180)\nscattered_lon = np.random.uniform(139.67, 139.80, 180)\n\nlatitude = np.concatenate([shinjuku_lat, shibuya_lat, ginza_lat, akiba_lat, scattered_lat])\nlongitude = np.concatenate([shinjuku_lon, shibuya_lon, ginza_lon, akiba_lon, scattered_lon])\n\n# Plot\nfig, ax = plt.subplots(figsize=(16, 9))\n\n# KDE geographic heatmap\nsns.kdeplot(\n    x=longitude,\n    y=latitude,\n    ax=ax,\n    fill=True,\n    cmap=\"YlOrRd\",\n    levels=30,\n    thresh=0.02,\n    alpha=0.85,\n    cbar=True,\n    cbar_kws={\"label\": \"Check-in Density\", \"shrink\": 0.8},\n)\n\n# Scatter overlay: individual check-in locations\nax.scatter(longitude, latitude, s=12, alpha=0.25, color=INK_MUTED, edgecolors=\"none\", zorder=5)\n\n# District labels provide geographic context\ndistricts = [\n    (\"Shinjuku\", 139.700, 35.701),\n    (\"Shibuya\", 139.699, 35.649),\n    (\"Ginza\", 139.763, 35.681),\n    (\"Akihabara\", 139.773, 35.709),\n]\nfor name, lon, lat in districts:\n    ax.text(lon, lat, name, fontsize=13, color=INK, ha=\"center\", va=\"center\", fontweight=\"semibold\", alpha=0.85)\n\n# Axis style\nax.set_xlabel(\"Longitude (°E)\", fontsize=20)\nax.set_ylabel(\"Latitude (°N)\", fontsize=20)\nax.set_title(\n    \"Tokyo Check-ins · heatmap-geographic · python · seaborn · anyplot.ai\",\n    fontsize=22,\n    fontweight=\"medium\",\n    color=INK,\n    pad=15,\n)\nax.tick_params(axis=\"both\", labelsize=16)\n\nax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f\"{x:.2f}°\"))\nax.yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f\"{y:.2f}°\"))\n\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor s in (\"left\", \"bottom\"):\n    ax.spines[s].set_color(INK_SOFT)\n\nax.grid(True, alpha=0.10, linewidth=0.8)\nax.set_aspect(\"equal\", adjustable=\"box\")\n\n# Style colorbar axes (theme-adaptive tick labels and label color)\nfor cbar_ax in fig.axes:\n    if cbar_ax is not ax:\n        cbar_ax.tick_params(labelsize=14, colors=INK_SOFT)\n        cbar_ax.yaxis.label.set_color(INK)\n        cbar_ax.yaxis.label.set_fontsize(18)\n        break\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}