One line of Python. A map worth sharing.
Military spending — encode="conquest" — countries "conquer" tiles proportional to their military spending
mappize turns any geographic dataset into a publication-ready, social-media-optimised map with a single function call.
No QGIS. No D3. No GeoJSON wrangling. Just:
from mappize import mappize
mappize("co2 emissions")It auto-fetches data from Our World in Data, merges it with world geometry, picks a great colour scale, adds a headline insight, and renders a beautiful map — all in under 10 seconds.
pip install mappizeRequires
geopandasfor full rendering. Install it withpip install geopandasor via conda.
from mappize import mappize
# Search Our World in Data by keyword
mappize("co2 emissions")
mappize("child mortality")
mappize("gdp per capita")
# Load a URL directly
mappize("https://raw.githubusercontent.com/owid/co2-data/master/owid-co2-data.csv")
# Or bring your own DataFrame
import pandas as pd
df = pd.read_csv("my_data.csv") # needs a country column + a numeric column
mappize(df)That's it. Every call auto-detects the geography, filters to the latest year, and renders.
The flagship feature: mappize.tiles() (alias: mappize.mosaic()).
Countries are rendered as grids of hexagons or squares, coloured by value.
Zoom to any of 100+ regions. Seven visual encoding modes. Totally customisable.
mappize.tiles("co2 emissions",
region = "europe", # world | europe | africa | germany | usa | 100+ names
shape = "hex", # "hex" (default) or "square"
tile_size= "m", # "xs" | "s" | "m" | "l" | "xl" or a float multiplier
vignette = True, # dark edge fade
encode = "iso", # see the 7 modes below
style = "mosaic", # 12 themes available
dark = True, # True = force dark | False = force light | None = auto
colors = {"bg": "#0D0D0D", "accent": "#FF4500", "cmap": "plasma"},
save = "map.png",
)Value → colour. The standard tile map.
Every tile rises by its value. High-emission countries become literal spikes.
Thin stems anchor each tile to the ground plane.
mappize.tiles("co2 emissions", encode="iso", tile_size="l", style="mosaic")Multi-layer transparent halos around every tile.
Works best on dark backgrounds — think city lights from orbit.
mappize.tiles("co2 emissions", encode="glow", style="dark", vignette=True)Each tile casts a drop shadow proportional to its value.
High-value tiles appear to float above the surface.
mappize.tiles("co2 emissions", region="middle east", encode="shadow",
shape="square", style="bloomberg")Tile size AND colour both encode the value. Double the signal.
High-value countries get more tiles per unit area.
The map morphs: dense = important.
Tile size encodes value; tiles filled with the theme accent colour.
Minimalist and striking.
| Parameter | Type | Default | Description |
|---|---|---|---|
source |
str | DataFrame |
— | Keyword, URL, or DataFrame |
year |
int |
latest | Filter to this year |
region |
str |
"world" |
Geographic scope — 100+ names |
shape |
str |
"hex" |
"hex" or "square" |
tile_size |
str | float |
"m" |
"xs" "s" "m" "l" "xl" or float multiplier |
encode |
str |
"color" |
"color" "size" "size+color" "density" "glow" "iso" "shadow" |
vignette |
bool | float |
False |
Dark edge fade. True = 0.78, or pass 0–1 |
style |
str |
"mosaic" |
Theme (see below) |
cell_size |
float |
auto | Cell radius in degrees (overrides auto-selection) |
dark |
bool | None |
None |
True = force dark variant, False = force light, None = keep style |
colors |
dict |
None |
Per-key overrides — see colour aliases below |
title |
str |
auto | Map title |
save |
str |
None |
Save path (.png, .jpg, .pdf) |
show |
bool |
True |
Display the figure |
World: "world"
Continents: "europe" "africa" "asia" "north america"
"south america" "oceania"
Sub-regions: "middle east" "caribbean" "central america" "latin america"
USA: "usa"
Countries: "germany" "france" "italy" "spain" "uk"
"india" "china" "brazil" "usa" "russia" "japan"
… and 90+ more (Afghanistan → Zimbabwe)
Beyond tiles, mappize ships eight renderers:
mappize("co2 emissions") # classic choropleth
mappize.tiles("co2 emissions") # tile / mosaic map ← the star
mappize.viral("co2 emissions") # 1200×628 social card (Twitter/LinkedIn)
mappize.bubble("co2 emissions") # bubble map with neon glow
mappize.spike("co2 emissions") # graduated bar chart on map
mappize.dot("co2 emissions") # dot-density / stipple
mappize.pixel("co2 emissions") # pixel-art mosaic (image-based)
mappize.attention("co2 emissions") # outlier-spotlight map
mappize.story("co2 emissions") # 4-slide narrative (title → map → attention → ranking)Any style can be flipped to its natural partner without choosing a new theme name:
mappize.tiles("co2 emissions", style="ft", dark=True) # FT salmon → Bloomberg dark
mappize.tiles("co2 emissions", style="mosaic", dark=False) # charcoal → editorial white| Light style | → Dark partner |
|---|---|
editorial |
dark |
ft |
bloomberg |
nytimes |
bloomberg |
light |
dark |
minimal |
dark |
mono |
cinder |
Pass a colors dict to override any theme colour. Friendly aliases are supported:
# Short aliases
mappize.tiles("co2 emissions",
colors={
"bg": "#0D0D0D", # background
"fg": "#FFFFFF", # text / foreground
"accent": "#FF4500", # headline colour + size-mode fill
"cmap": "plasma", # matplotlib colormap name
}
)
# Full key names also work
mappize.tiles("co2 emissions", style="mosaic",
colors={
"background": "#1A0A2E",
"accent": "#E040FB",
"map_cmap": "magma",
"missing_color":"#120020",
}
)Alias table
| Alias | Full key |
|---|---|
bg |
background |
fg / foreground |
text |
cmap / colormap |
map_cmap |
sub |
subtext |
border |
border_color |
missing |
missing_color |
dark and colors work on every renderer — tiles, viral, bubble, spike, etc.
# Dark
style = "mosaic" # charcoal + amber gold ← default for tiles
style = "cinder" # midnight navy + purple
style = "dark" # deep navy + cyan
style = "bloomberg" # near-black + orange plasma
style = "arctic" # dark ocean + ice blue
# Light
style = "editorial" # warm white (FAFAF5) — NYT/Guardian feel
style = "ft" # FT salmon (#FFF1E5)
style = "nytimes" # white + red
style = "light" # neutral grey
style = "minimal" # pure white
style = "mono" # black & whitemappize integrates with Our World in Data out of the box.
Use any keyword — the library fuzzy-matches it against a curated catalog:
mappize("co2 emissions") # CO₂ per capita (t)
mappize("energy consumption") # Primary energy per capita (kWh)
mappize("life expectancy") # Coming soon
mappize("gdp per capita") # Coming soon
mappize("https://...") # Any OWID raw CSV URLData is cached locally in ~/.mappize/data/ — no double downloads.
You can also pass any DataFrame with a country column:
import pandas as pd
df = pd.DataFrame({
"country": ["Germany", "France", "Italy", "Spain"],
"happiness_score": [7.0, 6.7, 6.2, 6.5],
})
mappize.tiles(df, region="europe", encode="glow", style="mosaic")from mappize import mappize
# The 3-D spike world
mappize.tiles("co2 emissions",
encode="iso", tile_size="l", style="mosaic", save="world_spikes.png")
# Neon glow continent
mappize.tiles("co2 emissions",
region="africa", encode="glow", style="dark", vignette=True)
# Ultra-fine pixel grid
mappize.tiles("co2 emissions",
region="europe", shape="square", tile_size="xs", vignette=0.5)
# Density cartogram (morphing map)
mappize.tiles("co2 emissions",
region="world", encode="density", style="mosaic", vignette=True)
# Social card ready to post
mappize.viral("co2 emissions", save="card.png")| mappize | matplotlib + geopandas | folium / plotly | |
|---|---|---|---|
| Lines of code | 1 | 40–80 | 20–50 |
| Tile-grid style | ✅ 7 modes | ❌ | ❌ |
| OWID integration | ✅ auto | ❌ | ❌ |
| Social-card export | ✅ | ❌ | ❌ |
| Offline | ✅ cached | ✅ | ❌ |
| Customisable | ✅ 12 themes | ✅ | limited |
PRs welcome. Run existing tests with:
pip install -e ".[dev]"
pytest tests/To add a new OWID dataset, extend mappize/owid.py:
"your keyword": {
"url": "https://raw.githubusercontent.com/owid/...",
"col": "column_name",
"title": "Human-Readable Title",
}MIT — free to use, fork, and build on.
Made with Python · Data from Our World in Data · Geometry from Natural Earth





