{"spec_id":"hexbin-map-geographic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nhexbin-map-geographic: Hexagonal Binning Map\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 87/100 | Updated: 2026-05-27\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib.colors import LinearSegmentedColormap\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.15,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Data: Simulated bird species observation locations in Pacific Northwest\nnp.random.seed(42)\nn_points = 7000\ncenter_lon, center_lat = -121.5, 46.8\nlon = np.random.normal(center_lon, 1.4, n_points)\nlat = np.random.normal(center_lat, 1.1, n_points)\n\n# Seattle urban birding hotspot (highest observer density)\nidx1 = np.where(np.random.random(n_points) < 0.22)[0]\nlon[idx1] = np.random.normal(-122.33, 0.10, len(idx1))\nlat[idx1] = np.random.normal(47.61, 0.08, len(idx1))\n\n# Portland urban birding area\nidx2 = np.where(np.random.random(n_points) < 0.18)[0]\nlon[idx2] = np.random.normal(-122.68, 0.09, len(idx2))\nlat[idx2] = np.random.normal(45.52, 0.07, len(idx2))\n\n# Cascade Range wilderness cluster\nidx3 = np.where(np.random.random(n_points) < 0.13)[0]\nlon[idx3] = np.random.normal(-121.2, 0.20, len(idx3))\nlat[idx3] = np.random.normal(47.1, 0.20, len(idx3))\n\n# Olympic Peninsula coastal hotspot\nidx4 = np.where(np.random.random(n_points) < 0.10)[0]\nlon[idx4] = np.random.normal(-123.7, 0.18, len(idx4))\nlat[idx4] = np.random.normal(47.9, 0.20, len(idx4))\n\n# Species richness score per observation (1–5); higher near urban birding hotspots.\n# Demonstrates mean aggregation — switch reduce_C_function=np.sum for sum aggregation.\nrichness = np.random.uniform(1.0, 3.0, n_points)\nrichness[idx1] += np.random.uniform(1.5, 2.0, len(idx1))  # Seattle: high richness\nrichness[idx2] += np.random.uniform(1.0, 1.5, len(idx2))  # Portland: moderate-high\nrichness = np.clip(richness, 1.0, 5.0)\n\ndf = pd.DataFrame({\"Longitude\": lon, \"Latitude\": lat, \"Richness\": richness})\n\n# imprint_seq: green (low richness) → blue (high richness) — anyplot sequential colormap\nimprint_seq = LinearSegmentedColormap.from_list(\"imprint_seq\", [\"#009E73\", \"#4467A3\"])\n\n# Plot — seaborn jointplot; square canvas: height=6, dpi=400 → 2400×2400 px\n# Mean aggregation per hexbin cell (count: omit C/reduce_C_function; sum: np.sum)\ng = sns.jointplot(\n    data=df,\n    x=\"Longitude\",\n    y=\"Latitude\",\n    kind=\"hex\",\n    cmap=imprint_seq,\n    mincnt=1,\n    gridsize=28,\n    marginal_kws={\"bins\": 30, \"color\": \"#009E73\", \"edgecolor\": PAGE_BG, \"alpha\": 0.75},\n    joint_kws={\n        \"C\": df[\"Richness\"].values,\n        \"reduce_C_function\": np.mean,\n        \"alpha\": 0.88,\n        \"edgecolors\": PAGE_BG,\n        \"linewidths\": 0.15,\n    },\n    height=6,\n    ratio=8,\n)\ng.figure.set_dpi(400)\n\n# Theme backgrounds\ng.figure.patch.set_facecolor(PAGE_BG)\nax = g.ax_joint\nax.set_facecolor(PAGE_BG)\ng.ax_marg_x.set_facecolor(PAGE_BG)\ng.ax_marg_y.set_facecolor(PAGE_BG)\n\n# Explicit geographic bounds covering Pacific Northwest\nax.set_xlim(-126.5, -116.5)\nax.set_ylim(43.0, 51.0)\n\n# --- Simplified Pacific NW geographic reference layer ---\ngeo_kw = {\"color\": INK_SOFT, \"alpha\": 0.55, \"lw\": 1.0, \"zorder\": 3, \"solid_capstyle\": \"round\"}\n\n# Pacific Coastline (approximate, south to north)\ncoast_lon = [-124.5, -124.4, -124.2, -124.1, -124.1, -124.3, -124.6, -124.7, -124.7]\ncoast_lat = [43.0, 44.5, 45.5, 46.2, 46.5, 47.0, 47.8, 48.2, 48.5]\nax.plot(coast_lon, coast_lat, **geo_kw)\n\n# US-Canada border (49°N)\nax.plot([-126.5, -124.6], [49.0, 49.0], linestyle=\"--\", **geo_kw)\nax.text(-125.2, 49.2, \"Canada\", fontsize=7, color=INK_MUTED, ha=\"center\", va=\"bottom\")\n\n# WA-OR border (Columbia River, simplified west to east)\nwa_or_lon = [-124.1, -123.5, -122.9, -122.3, -121.5, -120.5, -119.7, -118.5, -116.9]\nwa_or_lat = [46.2, 46.0, 45.6, 45.5, 45.6, 45.7, 45.9, 46.0, 46.1]\nax.plot(wa_or_lon, wa_or_lat, linestyle=\"--\", **geo_kw)\n\n# State labels (in sparse-data areas east of main cluster)\nax.text(-119.0, 48.5, \"WA\", fontsize=9, color=INK_MUTED, ha=\"center\", fontweight=\"medium\")\nax.text(-119.0, 44.5, \"OR\", fontsize=9, color=INK_MUTED, ha=\"center\", fontweight=\"medium\")\n\n# Spines\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor spine in (\"left\", \"bottom\"):\n    ax.spines[spine].set_color(INK_SOFT)\n\n# Axis labels and ticks\nax.set_xlabel(\"Longitude (°W)\", fontsize=10, color=INK)\nax.set_ylabel(\"Latitude (°N)\", fontsize=10, color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\n\n# Colorbar\ncbar = plt.colorbar(ax.collections[0], ax=ax, shrink=0.65, pad=0.02, aspect=22)\ncbar.set_label(\"Mean Species Richness\", fontsize=9, color=INK, labelpad=8)\ncbar.ax.tick_params(labelsize=7, colors=INK_SOFT)\ncbar.outline.set_edgecolor(INK_SOFT)\n\n# City labels with ELEVATED_BG background for readability over hexbins\nbbox_props = {\"boxstyle\": \"round,pad=0.2\", \"facecolor\": ELEVATED_BG, \"edgecolor\": \"none\", \"alpha\": 0.80}\nax.text(-122.33, 47.83, \"Seattle\", fontsize=8, color=INK, ha=\"center\", fontstyle=\"italic\", bbox=bbox_props, zorder=10)\nax.text(-122.68, 45.27, \"Portland\", fontsize=8, color=INK, ha=\"center\", fontstyle=\"italic\", bbox=bbox_props, zorder=10)\n\n# Title\ntitle = \"hexbin-map-geographic · python · seaborn · anyplot.ai\"\nn = len(title)\ntitle_fontsize = max(8, round(12 * (67 / n if n > 67 else 1.0)))\ng.figure.suptitle(title, fontsize=title_fontsize, color=INK, fontweight=\"medium\")\ng.figure.subplots_adjust(top=0.91)\n\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}