Skip to content

Donziglary/BirthAtlas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🌍 BirthAtlas

Exploring the Global Birth Lottery Through Data

Python Pandas Plotly License: MIT

🇬🇧 English | 🇮🇷 فارسی

🚀 Live Demo

👉 https://donziglary.github.io/BirthAtlas/

No installation needed — the demo runs entirely in your browser.


📖 Overview

BirthAtlas is a data visualization project that explores the probability of being born in a given country, in a given year.

Using official World Bank demographic data and the UNDP Human Development Index, the project estimates each country's annual share of global births and pairs that with a measure of human development for the same year. The result is presented two ways: an animated world map for exploring the global picture, and an interactive "Birth Story" panel that turns the raw numbers into a short, personal narrative for any country and year.

The project combines demographic analysis, statistical modeling, and interactive front-end engineering — from data cleaning in pandas to a hand-built Canvas-based image export — to turn raw population data into something people actually want to explore and share.


💡 Motivation

Every person is born into circumstances they never chose.

BirthAtlas explores this idea quantitatively, through a simple question:

If a person were selected at random from everyone ever born in the last three decades, in which country — and in which year — would that most likely have happened?

This is closely related to the philosophical idea of the Birth Lottery: the place and moment of birth are decided before anyone has any say in the matter, yet they shape the opportunities, living conditions, and life outcomes a person is born into.


✨ Features

World map

  • Interactive Plotly choropleth of global birth probability, 1993–2020
  • Animated timeline slider
  • Log-scaled color encoding tuned for this dataset's heavily skewed distribution
  • Country-level ranking and detailed hover tooltips

Your birth story

  • Pick any country and year (or let the page pick one for you) to see:
    • Birth probability, with a human-scale analogy ("rarer than a hole-in-one in golf")
    • World rank by birth share, and how it compares to that year's global average
    • Human Development Index and its rank, when available for that country/year
    • A birth-probability vs. HDI trend chart across the full time range
  • Download the result as a shareable 1200×630 image card, rendered entirely with the Canvas API
  • Subtle, restrained motion throughout (tab transitions, staggered reveals, an eased count-up on the headline number), fully disabled for anyone with prefers-reduced-motion set

Engineering details worth noting

  • Fully static: the whole site is one index.html file with no backend and no build step
  • Self-hosted fonts (no external font CDN dependency)
  • Defensive against the two classic causes of "broken on mobile, fine on desktop": Plotly's default-size fallbacks, and CSS Grid's implicit min-width: auto

📊 Methodology

For each country and year:

Births = Population × Birth Rate / 1000

Birth Probability (%) = (Country Births / Global Births) × 100

Human Development Index values come directly from UNDP's published composite index (already normalized 0–1) and are merged in by ISO-3 country code and year, not by country name — country names differ between the World Bank and UNDP sources (e.g. "Iran, Islamic Rep." vs. "Iran (Islamic Republic of)"), and an earlier version of this pipeline that joined on name silently dropped around 25 countries because of that mismatch.

HDI rank is computed within each year, not across the full dataset, since the number of countries with available HDI data changes from year to year.


📂 Repository Structure

BirthAtlas/
│
├── assets/
│   └── fonts/                    # Self-hosted Space Grotesk (all weights)
│
├── data/
│   ├── raw/                      # World Bank + UNDP source files
│   └── processed/                # Cleaned, merged datasets
│       ├── birth_probability.csv
│       └── birth_probability_hdi.csv
│
├── notebooks/
│   ├── 01_process_data.ipynb          # Clean & merge World Bank source data
│   ├── 02_add_hdi.ipynb               # Merge in UNDP HDI data
│   ├── 03_visualize.ipynb             # Builds index.html (map + Birth Story UI)
│   ├── 04_country_comparison.ipynb    # Comparison engine tests
│   ├── 05_birth_story.ipynb           # Narrative generation tests
│   └── 06_lottery_simulator.ipynb     # Random-birth simulator tests
│
├── src/
│   └── birth_atlas/               # Shared analysis logic (imported by notebooks 04–06)
│       ├── comparison.py          # get_country_summary, yearly stats
│       ├── narrative.py           # Birth Story text generation, odds-ladder analogies
│       └── simulator.py           # Weighted random birth simulator
│
├── index.html                     # Generated output — the live site
├── requirements.txt
├── LICENSE
└── README.md

notebooks/04 through 06 no longer define their own copies of the comparison, narrative, and simulator logic — that logic now lives once in src/birth_atlas/ and is imported. Each notebook keeps its own test/verification cells (including edge cases like missing HDI data) so the shared logic stays easy to validate in isolation.


🛠 Setup

git clone https://github.com/Donziglary/BirthAtlas.git
cd BirthAtlas
python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Run the notebooks in numerical order (0106) from the notebooks/ folder. Notebook 03_visualize.ipynb is the one that regenerates index.html; the rest are analysis and verification.

To just view the site without running anything, open index.html directly in a browser, or use the live demo.


🛠 Technologies

Data pipeline: Python, pandas, NumPy, Jupyter Notebook Visualization: Plotly (choropleth map, trend charts) Front end: vanilla HTML/CSS/JavaScript — no framework, no build step Image export: Canvas API (hand-drawn shareable cards, no external rendering library)


🌍 Data Sources


⚠️ Known Limitations

  • HDI data is unavailable for some country/year combinations (mainly smaller states and earlier years); the Birth Story panel handles this gracefully but the underlying gap is a real limitation of the source data, not something this project fills in.
  • Only fonts are self-hosted — Plotly.js and the flag-icons stylesheet are still loaded from CDNs, so a fully offline environment will lose the map and country flags (the rest of the page still works).
  • The narrative logic (odds-ladder analogies, Birth Story wording) exists in two places: src/birth_atlas/narrative.py (Python, used by notebooks) and a JavaScript reimplementation inside index.html (used by the live page). This is a deliberate trade-off — the site is a single static HTML file with no build step, so it cannot import the Python package directly — but it means the two must be kept in sync by hand. If the analogy wording or thresholds change, both places need updating.

🔮 Possible Future Directions

This project is currently a stable, complete release. If development continues, candidate directions include:

  • Birth probability forecasting (e.g. linear regression, Prophet, or a small time-series model) for future years
  • Regional/continental aggregation views
  • Additional socioeconomic indicators alongside HDI

📄 License

This project is released under the MIT License.

Releases

Packages

Contributors

Languages