{"spec_id":"choropleth-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nchoropleth-basic: Choropleth Map with Regional Coloring\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 78/100 | Updated: 2026-05-15\n\"\"\"\n\nimport os\nimport sys\n\n\n# Prevent matplotlib.py from shadowing the matplotlib package\nscript_dir = os.path.dirname(os.path.abspath(__file__))\nsys.path = [p for p in sys.path if os.path.abspath(p) != script_dir]\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\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# Country data with geographic coordinates (lat, lon) and life expectancy\ncountry_data = {\n    \"Canada\": {\"lat\": 56.1, \"lon\": -106.3, \"le\": 82},\n    \"United States\": {\"lat\": 37.1, \"lon\": -95.7, \"le\": 78},\n    \"Mexico\": {\"lat\": 23.6, \"lon\": -102.6, \"le\": 75},\n    \"Guatemala\": {\"lat\": 15.5, \"lon\": -90.3, \"le\": 74},\n    \"Cuba\": {\"lat\": 21.5, \"lon\": -77.8, \"le\": 79},\n    \"Colombia\": {\"lat\": 4.6, \"lon\": -74.1, \"le\": 76},\n    \"Brazil\": {\"lat\": -14.2, \"lon\": -51.9, \"le\": 76},\n    \"Peru\": {\"lat\": -9.2, \"lon\": -75.2, \"le\": 74},\n    \"Argentina\": {\"lat\": -38.4, \"lon\": -63.6, \"le\": 76},\n    \"Iceland\": {\"lat\": 64.9, \"lon\": -19.0, \"le\": 83},\n    \"United Kingdom\": {\"lat\": 55.4, \"lon\": -3.4, \"le\": 81},\n    \"France\": {\"lat\": 46.6, \"lon\": 2.2, \"le\": 83},\n    \"Germany\": {\"lat\": 51.2, \"lon\": 10.5, \"le\": 82},\n    \"Spain\": {\"lat\": 40.5, \"lon\": -3.7, \"le\": 84},\n    \"Italy\": {\"lat\": 41.9, \"lon\": 12.6, \"le\": 84},\n    \"Poland\": {\"lat\": 51.9, \"lon\": 19.1, \"le\": 79},\n    \"Russia\": {\"lat\": 61.5, \"lon\": 105.3, \"le\": 72},\n    \"Nigeria\": {\"lat\": 9.1, \"lon\": 8.7, \"le\": 54},\n    \"Egypt\": {\"lat\": 26.8, \"lon\": 30.8, \"le\": 72},\n    \"South Africa\": {\"lat\": -30.6, \"lon\": 22.9, \"le\": 65},\n    \"Kenya\": {\"lat\": -0.0, \"lon\": 37.9, \"le\": 67},\n    \"Saudi Arabia\": {\"lat\": 23.9, \"lon\": 45.1, \"le\": 76},\n    \"Iran\": {\"lat\": 32.4, \"lon\": 53.7, \"le\": 76},\n    \"Israel\": {\"lat\": 31.0, \"lon\": 35.2, \"le\": 82},\n    \"India\": {\"lat\": 20.6, \"lon\": 78.9, \"le\": 68},\n    \"Pakistan\": {\"lat\": 30.2, \"lon\": 69.3, \"le\": 67},\n    \"Bangladesh\": {\"lat\": 23.7, \"lon\": 90.4, \"le\": 73},\n    \"Thailand\": {\"lat\": 15.9, \"lon\": 100.9, \"le\": 77},\n    \"Indonesia\": {\"lat\": -0.8, \"lon\": 113.9, \"le\": 72},\n    \"Vietnam\": {\"lat\": 14.1, \"lon\": 108.8, \"le\": 74},\n    \"Philippines\": {\"lat\": 12.9, \"lon\": 121.8, \"le\": 72},\n    \"China\": {\"lat\": 35.9, \"lon\": 104.1, \"le\": 78},\n    \"Japan\": {\"lat\": 36.2, \"lon\": 138.3, \"le\": 84},\n    \"South Korea\": {\"lat\": 35.9, \"lon\": 127.8, \"le\": 83},\n    \"Australia\": {\"lat\": -25.3, \"lon\": 133.8, \"le\": 83},\n    \"New Zealand\": {\"lat\": -40.9, \"lon\": 174.9, \"le\": 82},\n}\n\n# Create figure with geographic extent\nfig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Prepare colormap and normalization\ncmap = plt.cm.RdYlGn\nnorm = plt.Normalize(vmin=54, vmax=84)\n\n# Calculate region sizes based on life expectancy (larger = higher life expectancy)\n# Scale from 0.4 to 1.2 for visual variety\nsize_scale = np.linspace(0.4, 1.2, 4)\n\n# Plot geographic regions with varying sizes\nfor country, data in country_data.items():\n    lat, lon, le = data[\"lat\"], data[\"lon\"], data[\"le\"]\n    color = cmap(norm(le))\n\n    # Create proportionally sized hex marker\n    size = 80 + (le - 54) * 8  # Scale marker size by life expectancy\n    ax.scatter(lon, lat, s=size, c=[color], edgecolors=INK_SOFT, linewidth=1, alpha=0.85, marker=\"H\", zorder=2)\n\n    # Add country label with theme-aware color\n    # Use light ink for low values, dark ink for high values\n    text_color = INK_SOFT if le < 70 else INK\n    ax.text(\n        lon,\n        lat,\n        country[:3].upper(),\n        ha=\"center\",\n        va=\"center\",\n        fontsize=9,\n        fontweight=\"bold\",\n        color=text_color,\n        zorder=3,\n    )\n\n# Set geographic bounds (world extent)\nax.set_xlim(-180, 180)\nax.set_ylim(-60, 85)\nax.set_aspect(\"equal\")\n\n# Remove axes for cleaner appearance\nax.set_xticks([])\nax.set_yticks([])\nfor spine in ax.spines.values():\n    spine.set_visible(False)\n\n# Add subtle grid for geographic reference\nax.grid(True, alpha=0.05, color=INK_SOFT, linewidth=0.5, linestyle=\":\")\nax.set_axisbelow(True)\n\n# Add colorbar\ncbar = plt.cm.ScalarMappable(cmap=cmap, norm=norm)\ncbar.set_array([])\ncbar_ax = fig.add_axes([0.92, 0.15, 0.015, 0.7])\ncbar_obj = plt.colorbar(cbar, cax=cbar_ax)\ncbar_obj.set_label(\"Life Expectancy (years)\", fontsize=18, color=INK)\ncbar_ax.tick_params(labelsize=14, colors=INK_SOFT)\nfor spine in cbar_ax.spines.values():\n    spine.set_color(INK_SOFT)\n\n# Title\ntitle = \"World Life Expectancy · choropleth-basic · matplotlib · anyplot.ai\"\nax.text(0.5, 1.02, title, transform=ax.transAxes, fontsize=24, fontweight=\"medium\", color=INK, ha=\"center\", va=\"bottom\")\n\nplt.tight_layout(rect=[0, 0, 0.9, 1])\n\n# Save to script directory\noutput_path = os.path.join(script_dir, f\"plot-{THEME}.png\")\nplt.savefig(output_path, dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}