Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions plots/choropleth-basic/implementations/pygal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
""" pyplots.ai
choropleth-basic: Choropleth Map with Regional Coloring
Library: pygal 3.1.0 | Python 3.13.11
Quality: 91/100 | Created: 2025-12-31
"""

import numpy as np
from pygal.style import Style
from pygal_maps_world.maps import World


# Data: GDP per capita (synthetic but realistic ranges)
np.random.seed(42)

# Select a diverse set of countries from different regions
country_codes = [
# Americas
"us",
"ca",
"mx",
"br",
"ar",
"cl",
"co",
"pe",
# Europe
"de",
"fr",
"gb",
"it",
"es",
"nl",
"se",
"no",
"pl",
"pt",
# Asia
"cn",
"jp",
"in",
"kr",
"id",
"th",
"vn",
"my",
# Africa
"za",
"eg",
"ng",
"ke",
"ma",
"gh",
# Oceania
"au",
"nz",
]

# Generate realistic GDP per capita values (in thousands USD)
high_income = ["us", "ca", "de", "fr", "gb", "nl", "se", "no", "jp", "kr", "au", "nz"]
upper_middle = ["mx", "br", "ar", "cl", "cn", "my", "za", "pl", "pt", "it", "es"]

gdp_data = {}
for code in country_codes:
if code in high_income:
gdp_data[code] = np.random.uniform(40, 85)
elif code in upper_middle:
gdp_data[code] = np.random.uniform(10, 40)
else:
gdp_data[code] = np.random.uniform(1, 15)

# Bin data into ranges for legend clarity
bins = [
("GDP < $10k", {k: v for k, v in gdp_data.items() if v < 10}),
("GDP $10k-$25k", {k: v for k, v in gdp_data.items() if 10 <= v < 25}),
("GDP $25k-$50k", {k: v for k, v in gdp_data.items() if 25 <= v < 50}),
("GDP > $50k", {k: v for k, v in gdp_data.items() if v >= 50}),
]

# Sequential blue palette for choropleth (light to dark)
colors = ["#a6cee3", "#6baed6", "#3182bd", "#08519c"]

# Custom style for large canvas
custom_style = Style(
background="white",
plot_background="white",
foreground="#333333",
foreground_strong="#111111",
foreground_subtle="#666666",
colors=tuple(colors),
title_font_size=80,
label_font_size=48,
legend_font_size=48,
major_label_font_size=40,
value_font_size=40,
tooltip_font_size=36,
no_data_font_size=36,
)

# Create world map
worldmap = World(
style=custom_style,
width=4800,
height=2700,
title="choropleth-basic \u00b7 pygal \u00b7 pyplots.ai",
show_legend=True,
legend_at_bottom=True,
legend_at_bottom_columns=4,
legend_box_size=40,
)

# Add each bin as a separate series
for label, data in bins:
worldmap.add(label, data)

# Save outputs
worldmap.render_to_file("plot.html")
worldmap.render_to_png("plot.png")
24 changes: 24 additions & 0 deletions plots/choropleth-basic/metadata/pygal.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
library: pygal
specification_id: choropleth-basic
created: '2025-12-31T13:57:54Z'
updated: '2025-12-31T14:09:13Z'
generated_by: claude-opus-4-5-20251101
workflow_run: 20620327898
issue: 3069
python_version: 3.13.11
library_version: 3.1.0
preview_url: https://storage.googleapis.com/pyplots-images/plots/choropleth-basic/pygal/plot.png
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/choropleth-basic/pygal/plot_thumb.png
preview_html: https://storage.googleapis.com/pyplots-images/plots/choropleth-basic/pygal/plot.html
quality_score: 91
review:
strengths:
- Excellent use of pygal_maps_world extension for creating a world choropleth map
- Sequential blue color palette is visually appealing and colorblind-accessible
- Good binning approach that creates clear visual distinctions between income levels
- Comprehensive geographic coverage spanning all major continents
- Custom Style properly scales fonts for the 4800x2700 canvas size
- Legend placement at bottom with 4 columns efficiently organizes the GDP ranges
weaknesses:
- Missing data countries shown as white rather than gray as suggested in spec
- Could leverage pygal's built-in tooltip/hover interactivity more prominently