{"spec_id":"map-projections","library":"pygal","language":"python","code":"\"\"\" anyplot.ai\nmap-projections: World Map with Different Projections\nLibrary: pygal 3.1.0 | Python 3.13.13\nQuality: 83/100 | Updated: 2026-05-23\n\"\"\"\n\nimport os\nimport sys\n\n\n# Remove this script's own directory from sys.path so 'pygal.py' doesn't shadow\n# the installed pygal package (a Python gotcha when the file shares a package name)\n_here = os.path.dirname(os.path.abspath(__file__))\nsys.path = [p for p in sys.path if os.path.abspath(p or \".\") != _here]\n\nfrom pygal.style import Style\nfrom pygal_maps_world.maps import World\n\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# anyplot_seq (4 stops, brand green → dark azure): maps equatorial→polar distortion\nZONE_COLORS = (\"#009E73\", \"#007E7E\", \"#005D89\", \"#003D94\")\n\n# Mercator distortion factor (≈ sec²φ, i.e. area exaggeration vs true size)\n# 1.0 = accurate at equator; higher = more bloated toward the poles in Mercator\ncountry_distortion = {\n    # ---- Polar zone (≥2.4×): extreme Mercator distortion ----\n    \"gl\": 14.3,  # Greenland ~72°N\n    \"ru\": 3.5,  # Russia ~61°N\n    \"ca\": 3.0,  # Canada ~60°N\n    \"no\": 2.8,  # Norway ~65°N\n    \"is\": 2.6,  # Iceland ~65°N\n    \"se\": 2.5,  # Sweden ~60°N\n    \"fi\": 2.4,  # Finland ~64°N\n    # ---- Temperate zone (1.2–2.4×): significant distortion ----\n    \"gb\": 2.3,  # United Kingdom ~54°N\n    \"pl\": 2.2,  # Poland ~52°N\n    \"be\": 2.1,  # Belgium ~51°N\n    \"nl\": 2.1,  # Netherlands ~52°N\n    \"de\": 2.1,  # Germany ~51°N\n    \"cz\": 2.0,  # Czech Republic ~50°N\n    \"at\": 2.0,  # Austria ~47°N\n    \"ch\": 2.0,  # Switzerland ~47°N\n    \"ua\": 2.0,  # Ukraine ~49°N\n    \"kz\": 2.0,  # Kazakhstan ~48°N\n    \"hu\": 1.9,  # Hungary ~47°N\n    \"ro\": 1.9,  # Romania ~46°N\n    \"fr\": 1.9,  # France ~46°N\n    \"us\": 1.9,  # United States ~38°N\n    \"mn\": 1.9,  # Mongolia ~46°N\n    \"it\": 1.8,  # Italy ~42°N\n    \"rs\": 1.8,  # Serbia ~44°N\n    \"bg\": 1.8,  # Bulgaria ~43°N\n    \"cl\": 1.7,  # Chile ~-36°S\n    \"nz\": 1.7,  # New Zealand ~-42°S\n    \"es\": 1.7,  # Spain ~40°N\n    \"pt\": 1.7,  # Portugal ~39°N\n    \"tr\": 1.7,  # Turkey ~39°N\n    \"ar\": 1.6,  # Argentina ~-38°S\n    \"gr\": 1.6,  # Greece ~39°N\n    \"kr\": 1.5,  # South Korea ~37°N\n    \"jp\": 1.5,  # Japan ~37°N\n    \"tn\": 1.5,  # Tunisia ~34°N\n    \"cn\": 1.5,  # China ~37°N\n    \"ir\": 1.4,  # Iran ~32°N\n    \"af\": 1.4,  # Afghanistan ~33°N\n    \"ma\": 1.4,  # Morocco ~32°N\n    \"au\": 1.3,  # Australia ~-27°S\n    \"pk\": 1.3,  # Pakistan ~30°N\n    \"dz\": 1.3,  # Algeria ~28°N\n    # ---- Subtropical zone (1.1–1.2×): moderate distortion ----\n    \"eg\": 1.15,  # Egypt ~26°N\n    \"sa\": 1.15,  # Saudi Arabia ~24°N\n    \"ae\": 1.15,  # UAE ~24°N\n    \"om\": 1.15,  # Oman ~22°N\n    \"tw\": 1.15,  # Taiwan ~24°N\n    \"bd\": 1.15,  # Bangladesh ~24°N\n    \"cu\": 1.15,  # Cuba ~22°N\n    \"py\": 1.15,  # Paraguay ~-23°S\n    \"mg\": 1.15,  # Madagascar ~-20°S\n    \"na\": 1.15,  # Namibia ~-22°S\n    \"bw\": 1.15,  # Botswana ~-22°S\n    \"za\": 1.15,  # South Africa ~-29°S\n    \"mx\": 1.1,  # Mexico ~23°N\n    \"in\": 1.1,  # India ~21°N\n    \"mm\": 1.1,  # Myanmar ~17°N\n    \"la\": 1.1,  # Laos ~18°N\n    \"sd\": 1.1,  # Sudan ~16°N\n    \"ne\": 1.1,  # Niger ~17°N\n    \"ml\": 1.1,  # Mali ~17°N\n    \"mr\": 1.1,  # Mauritania ~20°N\n    \"td\": 1.1,  # Chad ~15°N\n    \"ye\": 1.1,  # Yemen ~16°N\n    \"mz\": 1.1,  # Mozambique ~-18°S\n    \"bo\": 1.1,  # Bolivia ~-17°S\n    \"do\": 1.1,  # Dominican Rep. ~19°N\n    # ---- Equatorial zone (<1.1×): minimal distortion ----\n    \"br\": 1.0,  # Brazil\n    \"co\": 1.0,  # Colombia\n    \"ve\": 1.0,  # Venezuela\n    \"pe\": 1.0,  # Peru\n    \"ec\": 1.0,  # Ecuador\n    \"ng\": 1.0,  # Nigeria\n    \"cd\": 1.0,  # DR Congo\n    \"ao\": 1.0,  # Angola\n    \"cm\": 1.0,  # Cameroon\n    \"cg\": 1.0,  # Rep. of Congo\n    \"ga\": 1.0,  # Gabon\n    \"cf\": 1.0,  # Central African Rep.\n    \"et\": 1.0,  # Ethiopia\n    \"ke\": 1.0,  # Kenya\n    \"tz\": 1.0,  # Tanzania\n    \"ug\": 1.0,  # Uganda\n    \"ss\": 1.0,  # South Sudan\n    \"so\": 1.0,  # Somalia\n    \"rw\": 1.0,  # Rwanda\n    \"zm\": 1.0,  # Zambia\n    \"gh\": 1.0,  # Ghana\n    \"ci\": 1.0,  # Côte d'Ivoire\n    \"sn\": 1.0,  # Senegal\n    \"gn\": 1.0,  # Guinea\n    \"sl\": 1.0,  # Sierra Leone\n    \"lr\": 1.0,  # Liberia\n    \"tg\": 1.0,  # Togo\n    \"bj\": 1.0,  # Benin\n    \"id\": 1.0,  # Indonesia\n    \"my\": 1.0,  # Malaysia\n    \"ph\": 1.0,  # Philippines\n    \"th\": 1.0,  # Thailand\n    \"vn\": 1.0,  # Vietnam\n    \"kh\": 1.0,  # Cambodia\n    \"pg\": 1.0,  # Papua New Guinea\n}\n\nequatorial_zone = {k: v for k, v in country_distortion.items() if v < 1.1}\nsubtropical_zone = {k: v for k, v in country_distortion.items() if 1.1 <= v < 1.2}\ntemperate_zone = {k: v for k, v in country_distortion.items() if 1.2 <= v < 2.4}\npolar_zone = {k: v for k, v in country_distortion.items() if v >= 2.4}\n\ncustom_style = Style(\n    background=PAGE_BG,\n    plot_background=PAGE_BG,\n    foreground=INK,\n    foreground_strong=INK,\n    foreground_subtle=INK_MUTED,\n    colors=ZONE_COLORS,\n    title_font_size=66,\n    label_font_size=56,\n    major_label_font_size=44,\n    legend_font_size=44,\n    value_font_size=36,\n    stroke_width=2.5,\n)\n\nworldmap = World(\n    style=custom_style,\n    width=3200,\n    height=1800,\n    title=\"map-projections · python · pygal · anyplot.ai\",\n    show_legend=True,\n    legend_at_bottom=True,\n    legend_at_bottom_columns=4,\n    legend_box_size=40,\n    print_values=False,\n    print_labels=False,\n)\n\n# Zones ordered equatorial→polar so ZONE_COLORS maps low→high distortion\n# Labels shortened to prevent truncation in pygal's SVG renderer\nworldmap.add(\"0°–15° · <1.1×\", equatorial_zone)\nworldmap.add(\"15°–30° · 1.1–1.2×\", subtropical_zone)\nworldmap.add(\"30°–60° · 1.2–2.4×\", temperate_zone)\nworldmap.add(\"60°+ · ≥2.4×\", polar_zone)\n\nworldmap.render_to_png(f\"plot-{THEME}.png\")\nwith open(f\"plot-{THEME}.html\", \"wb\") as f:\n    f.write(worldmap.render())\n"}