{"spec_id":"contour-map-geographic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\ncontour-map-geographic: Contour Lines on Geographic Map\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 83/100 | Updated: 2026-05-20\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\"\nOCEAN = \"#C4D8EC\" if THEME == \"light\" else \"#182633\"\nLAND = \"#D8CEA8\" if THEME == \"light\" else \"#5A5040\"\nCOAST = \"#7A7264\" if THEME == \"light\" else \"#8A8070\"\nHIGHLIGHT = \"#C475FD\"  # Okabe-Ito warm orange — highlights Arctic signal\n\n# Simplified world coastline polygons (major continents)\nWORLD_COASTLINES = [\n    # North America\n    [\n        (-168, 66),\n        (-141, 70),\n        (-130, 70),\n        (-120, 60),\n        (-125, 50),\n        (-125, 40),\n        (-117, 33),\n        (-105, 25),\n        (-97, 26),\n        (-82, 25),\n        (-81, 30),\n        (-75, 35),\n        (-70, 42),\n        (-67, 45),\n        (-60, 47),\n        (-55, 52),\n        (-60, 60),\n        (-65, 68),\n        (-80, 70),\n        (-100, 73),\n        (-120, 75),\n        (-145, 72),\n        (-168, 66),\n    ],\n    # South America\n    [\n        (-82, 10),\n        (-77, 0),\n        (-80, -5),\n        (-70, -15),\n        (-60, -5),\n        (-50, 0),\n        (-35, -5),\n        (-40, -23),\n        (-55, -35),\n        (-68, -55),\n        (-75, -50),\n        (-75, -40),\n        (-70, -20),\n        (-80, -5),\n        (-82, 10),\n    ],\n    # Europe\n    [\n        (-10, 36),\n        (-10, 45),\n        (-5, 48),\n        (0, 52),\n        (5, 55),\n        (10, 58),\n        (20, 60),\n        (28, 70),\n        (35, 70),\n        (30, 60),\n        (25, 55),\n        (20, 50),\n        (15, 45),\n        (20, 40),\n        (25, 35),\n        (35, 35),\n        (28, 42),\n        (20, 38),\n        (10, 38),\n        (-10, 36),\n    ],\n    # Africa\n    [\n        (-17, 15),\n        (-17, 28),\n        (-5, 36),\n        (10, 38),\n        (20, 33),\n        (35, 30),\n        (45, 12),\n        (52, 12),\n        (45, 0),\n        (42, -10),\n        (35, -25),\n        (25, -34),\n        (18, -35),\n        (12, -20),\n        (15, -5),\n        (5, 5),\n        (-10, 5),\n        (-17, 15),\n    ],\n    # Asia\n    [\n        (35, 30),\n        (45, 42),\n        (52, 45),\n        (70, 42),\n        (80, 30),\n        (75, 15),\n        (90, 22),\n        (100, 15),\n        (105, 22),\n        (110, 5),\n        (120, 25),\n        (130, 35),\n        (140, 45),\n        (145, 55),\n        (135, 70),\n        (100, 78),\n        (70, 75),\n        (50, 70),\n        (30, 70),\n        (35, 50),\n        (45, 45),\n        (35, 30),\n    ],\n    # Australia\n    [\n        (113, -22),\n        (120, -18),\n        (135, -12),\n        (145, -15),\n        (152, -25),\n        (150, -38),\n        (140, -38),\n        (130, -33),\n        (115, -35),\n        (113, -22),\n    ],\n]\n\n# Data: Global temperature anomaly grid (simulated climate data)\nnp.random.seed(42)\n\nlon = np.linspace(-180, 180, 72)\nlat = np.linspace(-70, 85, 32)\nLON, LAT = np.meshgrid(lon, lat)\n\n# Realistic temperature anomaly: higher anomalies at poles (Arctic amplification)\nanomaly_base = 0.5 + 1.5 * (np.abs(LAT) / 90) ** 1.5\nanomaly_regional = 0.8 * np.sin(np.radians(LON * 2)) * np.cos(np.radians(LAT * 1.5)) + 0.6 * np.cos(\n    np.radians(LON + 60)\n) * np.sin(np.radians(LAT * 2))\nnoise = np.random.randn(32, 72) * 0.3\nZ = np.clip(anomaly_base + anomaly_regional + noise, -2.0, 4.5)\n\n# Apply seaborn theme with full theme-adaptive chrome\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# Canvas — landscape 3200×1800 px: main geographic map + zonal mean side panel\nfig, (ax_map, ax_zone) = plt.subplots(\n    1, 2, figsize=(8, 4.5), dpi=400, gridspec_kw={\"width_ratios\": [4, 1], \"wspace\": 0.06}\n)\nfig.patch.set_facecolor(PAGE_BG)\n\n# --- Geographic contour map ---\nax_map.set_facecolor(OCEAN)\nax_map.set_xlim(-180, 180)\nax_map.set_ylim(-70, 85)\n\n# Filled contours — BrBG_r: warm brown = positive anomaly, teal = negative\nlevels = np.linspace(-2, 4.5, 14)\ncontourf_plot = ax_map.contourf(LON, LAT, Z, levels=levels, cmap=\"BrBG_r\", alpha=0.85, extend=\"both\", zorder=1)\n\n# Contour lines at every other level (alpha increased for visibility)\ncontour_lines = ax_map.contour(LON, LAT, Z, levels=levels[::2], colors=INK, linewidths=0.8, alpha=0.75, zorder=2)\nax_map.clabel(contour_lines, inline=True, fontsize=8, fmt=\"%.1f°C\", colors=INK)\n\n# Coastlines with land fill for geographic context\nfor coastline in WORLD_COASTLINES:\n    if len(coastline) > 2:\n        lons = [p[0] for p in coastline]\n        lats = [p[1] for p in coastline]\n        ax_map.fill(lons, lats, color=LAND, edgecolor=COAST, linewidth=1.2, zorder=3)\n\n# Colorbar\ncbar = fig.colorbar(contourf_plot, ax=ax_map, shrink=0.80, pad=0.02, aspect=30)\ncbar.set_label(\"Temperature Anomaly (°C)\", fontsize=9, color=INK)\ncbar.ax.tick_params(labelsize=7, colors=INK_SOFT)\ncbar.outline.set_edgecolor(INK_SOFT)\n\nax_map.set_xlabel(\"Longitude (°)\", fontsize=10, color=INK)\nax_map.set_ylabel(\"Latitude (°)\", fontsize=10, color=INK)\nax_map.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\nax_map.grid(True, alpha=0.10, linewidth=0.5, color=INK_SOFT, zorder=0)\nax_map.set_axisbelow(True)\nax_map.spines[\"top\"].set_visible(False)\nax_map.spines[\"right\"].set_visible(False)\nax_map.spines[\"left\"].set_color(INK_SOFT)\nax_map.spines[\"bottom\"].set_color(INK_SOFT)\n\n# --- Zonal mean profile — seaborn lineplot shows Arctic amplification signal ---\nzonal_mean = Z.mean(axis=1)  # mean anomaly over all longitudes per latitude band\n\nsns.lineplot(x=zonal_mean, y=lat, ax=ax_zone, color=HIGHLIGHT, linewidth=2.0, errorbar=None)\nax_zone.fill_betweenx(lat, 0, zonal_mean, where=(zonal_mean > 0), color=HIGHLIGHT, alpha=0.15)\n\n# Zero reference line\nax_zone.axvline(0, color=INK_SOFT, linewidth=0.8, linestyle=\"--\", alpha=0.6)\n\n# Mark 60°N — boundary of Arctic amplification zone\nax_zone.axhline(60, color=HIGHLIGHT, linewidth=0.7, linestyle=\":\", alpha=0.7)\nax_zone.text(\n    0.55, 0.93, \"Arctic\\nAmplification\", transform=ax_zone.transAxes, fontsize=6, color=HIGHLIGHT, ha=\"center\", va=\"top\"\n)\n\nax_zone.set_ylim(-70, 85)\nax_zone.set_title(\"Zonal\\nMean\", fontsize=8, color=INK, pad=4)\nax_zone.set_xlabel(\"Anomaly\\n(°C)\", fontsize=8, color=INK)\nax_zone.tick_params(axis=\"x\", labelsize=7, colors=INK_SOFT)\nax_zone.set_yticks([])\nax_zone.grid(True, alpha=0.10, linewidth=0.5, color=INK_SOFT)\nax_zone.set_facecolor(PAGE_BG)\nax_zone.spines[\"top\"].set_visible(False)\nax_zone.spines[\"right\"].set_visible(False)\nax_zone.spines[\"left\"].set_visible(False)\nax_zone.spines[\"bottom\"].set_color(INK_SOFT)\n\nfig.suptitle(\n    \"Global Temperature Anomaly · contour-map-geographic · python · seaborn · anyplot.ai\",\n    fontsize=11,\n    fontweight=\"bold\",\n    x=0.5,\n    y=0.98,\n    color=INK,\n)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}