{"spec_id":"bubble-map-geographic","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nbubble-map-geographic: Bubble Map with Sized Geographic Markers\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-18\n\"\"\"\n\nimport os\nimport sys\n\nimport pandas as pd\n\n\n# Work around filename shadowing the altair library\nsys.path.pop(0)\nimport altair as alt\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\"\nLAND_FILL = \"#E8E4DC\" if THEME == \"light\" else \"#2C2C28\"\nLAND_STROKE = \"#B0AFA8\" if THEME == \"light\" else \"#4A4A44\"\n\n# Okabe-Ito positions 1-4 for tectonic regions\nREGION_COLORS = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Major earthquakes (M ≥ 6.0), 20th–21st century\n# Source: USGS Significant Earthquake Catalog\nearthquakes = {\n    \"name\": [\n        \"Tōhoku, Japan\",\n        \"Sumatra-Andaman\",\n        \"Hokkaido, Japan\",\n        \"Java, Indonesia\",\n        \"Solomon Islands\",\n        \"Kuril Islands\",\n        \"Sea of Okhotsk\",\n        \"Christchurch, NZ\",\n        \"Tonga\",\n        \"Kamchatka, Russia\",\n        \"Valdivia, Chile\",\n        \"Bio-Bio, Chile\",\n        \"Michoacan, Mexico\",\n        \"Haiti\",\n        \"Ecuador\",\n        \"Bolivia (deep)\",\n        \"Peru\",\n        \"El Salvador\",\n        \"Costa Rica\",\n        \"Alaska\",\n        \"Turkey-Syria\",\n        \"Izmit, Turkey\",\n        \"Zagros, Iran\",\n        \"Bam, Iran\",\n        \"Nepal\",\n        \"Gujarat, India\",\n        \"Pakistan (AJK)\",\n        \"Hindu Kush\",\n        \"Sichuan, China\",\n        \"Yunnan, China\",\n    ],\n    \"latitude\": [\n        38.3,\n        3.3,\n        42.16,\n        -9.35,\n        -8.47,\n        46.55,\n        54.89,\n        -43.58,\n        -18.0,\n        52.75,\n        -38.14,\n        -35.9,\n        18.19,\n        18.44,\n        0.36,\n        -13.84,\n        -5.76,\n        13.04,\n        10.39,\n        61.0,\n        37.22,\n        40.75,\n        26.75,\n        29.00,\n        28.15,\n        23.36,\n        34.55,\n        36.07,\n        31.00,\n        25.07,\n    ],\n    \"longitude\": [\n        142.37,\n        95.98,\n        142.86,\n        107.35,\n        157.04,\n        153.30,\n        153.28,\n        172.68,\n        -174.0,\n        159.5,\n        -73.41,\n        -72.73,\n        -102.53,\n        -72.57,\n        -79.94,\n        -67.55,\n        -75.27,\n        -88.66,\n        -85.24,\n        -147.5,\n        37.02,\n        29.99,\n        57.6,\n        58.37,\n        84.71,\n        70.34,\n        73.59,\n        70.49,\n        103.32,\n        99.31,\n    ],\n    \"magnitude\": [\n        9.1,\n        9.1,\n        8.3,\n        7.7,\n        8.1,\n        8.3,\n        8.3,\n        6.3,\n        7.4,\n        9.0,\n        9.5,\n        8.8,\n        8.0,\n        7.0,\n        7.8,\n        8.2,\n        8.0,\n        7.7,\n        7.6,\n        9.2,\n        7.8,\n        7.6,\n        6.8,\n        6.6,\n        7.8,\n        7.7,\n        7.6,\n        6.1,\n        7.9,\n        6.2,\n    ],\n    \"region\": [\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"East & SE Asia\",\n        \"Americas\",\n        \"Americas\",\n        \"Americas\",\n        \"Americas\",\n        \"Americas\",\n        \"Americas\",\n        \"Americas\",\n        \"Americas\",\n        \"Americas\",\n        \"Americas\",\n        \"Middle East & C. Asia\",\n        \"Middle East & C. Asia\",\n        \"Middle East & C. Asia\",\n        \"Middle East & C. Asia\",\n        \"South Asia\",\n        \"South Asia\",\n        \"South Asia\",\n        \"South Asia\",\n        \"South Asia\",\n        \"South Asia\",\n    ],\n}\n\ndf = pd.DataFrame(earthquakes)\n\n# World map basemap via vega-datasets CDN (no local package required)\nworld_url = \"https://cdn.jsdelivr.net/npm/vega-datasets@2/data/world-110m.json\"\ncountries = alt.topo_feature(world_url, \"countries\")\n\n# Base map layer: country boundaries\nbase_map = (\n    alt.Chart(countries)\n    .mark_geoshape(fill=LAND_FILL, stroke=LAND_STROKE, strokeWidth=0.5)\n    .project(type=\"equirectangular\", scale=280, translate=[800, 480])\n    .properties(width=1600, height=900)\n)\n\n# Earthquake bubble layer\nregion_order = [\"East & SE Asia\", \"Americas\", \"Middle East & C. Asia\", \"South Asia\"]\n\nbubbles = (\n    alt.Chart(df)\n    .mark_circle(opacity=0.65, stroke=PAGE_BG, strokeWidth=1.5)\n    .encode(\n        longitude=\"longitude:Q\",\n        latitude=\"latitude:Q\",\n        size=alt.Size(\n            \"magnitude:Q\",\n            scale=alt.Scale(domain=[6.0, 9.5], range=[80, 2800]),\n            legend=alt.Legend(\n                title=\"Magnitude\",\n                titleFontSize=16,\n                labelFontSize=14,\n                orient=\"bottom-left\",\n                offset=20,\n                values=[6.5, 7.5, 8.5, 9.5],\n                symbolFillColor=\"#009E73\",\n            ),\n        ),\n        color=alt.Color(\n            \"region:N\",\n            scale=alt.Scale(domain=region_order, range=REGION_COLORS),\n            legend=alt.Legend(\n                title=\"Tectonic Region\", titleFontSize=16, labelFontSize=14, orient=\"bottom-right\", offset=20\n            ),\n        ),\n        tooltip=[\n            alt.Tooltip(\"name:N\", title=\"Location\"),\n            alt.Tooltip(\"magnitude:Q\", title=\"Magnitude\", format=\".1f\"),\n            alt.Tooltip(\"region:N\", title=\"Region\"),\n            alt.Tooltip(\"latitude:Q\", title=\"Latitude\", format=\".2f\"),\n            alt.Tooltip(\"longitude:Q\", title=\"Longitude\", format=\".2f\"),\n        ],\n    )\n    .project(type=\"equirectangular\", scale=280, translate=[800, 480])\n)\n\n# Compose and apply theme-adaptive chrome\nchart = (\n    (base_map + bubbles)\n    .properties(\n        title=alt.Title(\n            text=\"Major Earthquakes · bubble-map-geographic · python · altair · anyplot.ai\",\n            fontSize=26,\n            anchor=\"middle\",\n            color=INK,\n        ),\n        width=1600,\n        height=900,\n        background=PAGE_BG,\n    )\n    .configure_view(fill=PAGE_BG, stroke=None)\n    .configure_title(color=INK)\n    .configure_legend(\n        fillColor=ELEVATED_BG, strokeColor=INK_SOFT, titleColor=INK, labelColor=INK_SOFT, padding=15, cornerRadius=5\n    )\n)\n\n# Save\nchart.save(f\"plot-{THEME}.png\", scale_factor=3.0)\nchart.save(f\"plot-{THEME}.html\")\n"}