A comprehensive implementation of the full ggplot2 grammar-of-graphics framework in Python using plotnine, producing 20+ charts across 12 core concepts. Each concept is demonstrated with a dedicated chart and side-by-side wrong/correct or before/after comparisons where applicable.
| Attribute | Detail |
|---|---|
| Language | Python 3 |
| Core Library | plotnine (R ggplot2 equivalent in Python) |
| Datasets | Gapminder (142 countries, 1952–2007) · GSS Survey (2,867 respondents, synthetic) |
| Charts Produced | 20+ across 12 core ggplot2 concepts |
| Notebook | ggplot2_All12_Concepts.ipynb |
Gapminder — gapminder (PyPI package)
- 142 countries across 12 time points (1952–2007, every 5 years)
- Variables:
country,continent,year,lifeExp,gdpPercap,pop - Derived column:
log_gdp = log(gdpPercap)
GSS Survey — Synthetic GSS-style data (N = 2,867)
- Variables:
age,childs,sex,race,religion,bigregion,degree - Distributions calibrated to match General Social Survey population proportions
- Seed:
np.random.seed(42)for reproducibility
| # | Concept | Chart Type | Key Demonstration |
|---|---|---|---|
| 1 | aes() mapping |
Scatter | 4 simultaneous aesthetics: x, y, color, size |
| 2 | geom_line() |
Line chart | Wrong (no group=) vs correct (group=country) |
| 3 | geom_point() |
Scatter | alpha, size, overplotting control |
| 4 | geom_bar() |
Bar chart | Auto-count stat; plain vs fill-encoded |
| 5 | geom_smooth() |
Scatter + trend | se=True (ribbon) vs se=False (clean line) |
| 6 | facet_wrap() |
Small-multiples | Default layout vs nrow=1; one-variable faceting |
| 7 | facet_grid() |
2D panel grid | Two-variable row × col faceting |
| 8 | scale_y_log10() |
Log-scaled axis | Before/after: skewed GDP normalized with dollar labels |
| 9 | scale_x_continuous() |
Custom axis | Dollar-formatted tick labels ($30k, $60k) |
| 10 | labs() |
Any | Bare plot vs full title, subtitle, caption, axis, legend |
| 11 | guides() |
Any | Redundant legend suppression; when to keep vs remove |
| 12 | position= |
Bar chart | stack → dodge → fill progression |
pip install plotnine gapminderimport pandas as pd
import numpy as np
from plotnine import *
from gapminder import gapminderNo external data files required — both datasets are generated in the setup cell. Run all cells top to bottom.
Chart 2 — geom_line() Wrong vs Correct
The most common ggplot2 mistake: omitting group=country collapses all 142 countries into a single jagged line. Chart 2a shows the broken output; Chart 2b shows the fix with group=country.
Chart 6 — facet_wrap() Three Variants
Three layouts demonstrated: default 2-row wrap by continent, nrow=1 single-row (matching the lecture 04 style), and a GSS age × children scatter faceted by sex.
Chart 8 — scale_y_log10() Before/After
Kuwait's GDP spike dominates the raw y-axis and compresses all other countries. Log transformation makes all 142 country trends readable simultaneously — the canonical use case for log-scale in data analytics.
Chart 11 — guides() Three-Panel Sequence
Shows exactly when to suppress vs keep a legend: redundant (suppress), redundant with color (suppress), two different variables mapped to x and fill (keep).
Chart 12 — Position Variants
Full stack → dodge → fill progression on religion × census region data — demonstrating when each encoding is appropriate for categorical composition analysis.
├── ggplot2_All12_Concepts.ipynb # Main notebook — all 12 concepts, 20+ charts
└── README.md
aes()controls all data-driven visual mappings; fixed properties (e.g.color='gray') go outsideaes()group=is mandatory forgeom_line()on multi-series data — the single most common ggplot2 errorscale_y_log10()is the correct tool for right-skewed distributions (GDP, costs, population)facet_wrap()splits by one variable;facet_grid()splits by two in a true 2D layoutguides(fill=False)removes a legend whenx=andfill=encode the same variableposition='fill'normalizes to 100% for rate comparison;position='dodge'enables direct value comparison
- plotnine documentation
- ggplot2 documentation
- Gapminder dataset: Hans Rosling / Gapminder Foundation
- GSS: NORC at the University of Chicago (synthetic approximation)