diff --git a/plots/scatter-size-mapped/implementations/pygal.py b/plots/scatter-size-mapped/implementations/pygal.py new file mode 100644 index 0000000000..b9552669bb --- /dev/null +++ b/plots/scatter-size-mapped/implementations/pygal.py @@ -0,0 +1,96 @@ +""" pyplots.ai +scatter-size-mapped: Bubble Chart +Library: pygal 3.1.0 | Python 3.13.11 +Quality: 91/100 | Created: 2025-12-27 +""" + +import numpy as np +import pygal +from pygal.style import Style + + +# Data: Country economic indicators +np.random.seed(42) + +# Generate 40 synthetic countries across different regions +n_countries = 40 +regions = ["Europe", "Asia", "Americas", "Africa"] + +# Assign regions with some variation +region_assignments = np.random.choice(regions, n_countries) + +# GDP per capita (1,000 - 80,000) +gdp_per_capita = np.random.uniform(5000, 75000, n_countries) +# Adjust by region for realism +for i, region in enumerate(region_assignments): + if region == "Europe": + gdp_per_capita[i] = np.random.uniform(25000, 75000) + elif region == "Asia": + gdp_per_capita[i] = np.random.uniform(5000, 60000) + elif region == "Americas": + gdp_per_capita[i] = np.random.uniform(8000, 70000) + else: # Africa + gdp_per_capita[i] = np.random.uniform(1000, 20000) + +# Life expectancy (50-85) correlated with GDP +life_expectancy = 50 + 30 * (gdp_per_capita / 80000) + np.random.uniform(-5, 5, n_countries) +life_expectancy = np.clip(life_expectancy, 50, 85) + +# Population (log scale, 1M - 1.4B) +population = 10 ** np.random.uniform(6, 9.2, n_countries) + +# Create custom style with larger font sizes for better rendering +custom_style = Style( + background="white", + plot_background="white", + foreground="#333333", + foreground_strong="#333333", + foreground_subtle="#666666", + colors=("#306998", "#FFD43B", "#E74C3C", "#27AE60", "#9B59B6"), + title_font_size=84, + label_font_size=56, + major_label_font_size=48, + legend_font_size=44, + value_font_size=40, + opacity=0.6, + opacity_hover=0.8, +) + +# Title with size legend information +title = "scatter-size-mapped · pygal · pyplots.ai\nBubble Size = Population (1M to 1B+)" + +# Create XY chart for scatter plot +chart = pygal.XY( + width=4800, + height=2700, + style=custom_style, + title=title, + x_title="GDP per Capita (USD)", + y_title="Life Expectancy (years)", + show_legend=True, + legend_at_bottom=True, + legend_at_bottom_columns=4, + dots_size=15, + show_x_guides=True, + show_y_guides=True, + stroke=False, + explicit_size=True, + truncate_legend=-1, +) + +# Group data by region and add as series +# Pygal XY chart uses value dict with 'value' for coordinates +for region in regions: + mask = region_assignments == region + points = [] + for i in np.where(mask)[0]: + # Scale population to reasonable dot size (log scale) + # Population ranges from 1M to 1.4B, scale to 12-70 for better visibility + # Increased minimum size from 5 to 12 so smaller bubbles are visible + size = 12 + 58 * (np.log10(population[i]) - 6) / 3.2 + points.append({"value": (float(gdp_per_capita[i]), float(life_expectancy[i])), "node": {"r": size}}) + chart.add(region, points) + +# Render to files +chart.render_to_png("plot.png") +chart.render_to_file("plot.html") diff --git a/plots/scatter-size-mapped/metadata/pygal.yaml b/plots/scatter-size-mapped/metadata/pygal.yaml new file mode 100644 index 0000000000..c15dd02c39 --- /dev/null +++ b/plots/scatter-size-mapped/metadata/pygal.yaml @@ -0,0 +1,29 @@ +library: pygal +specification_id: scatter-size-mapped +created: '2025-12-27T19:31:03Z' +updated: '2025-12-27T19:43:26Z' +generated_by: claude-opus-4-5-20251101 +workflow_run: 20543371845 +issue: 0 +python_version: 3.13.11 +library_version: 3.1.0 +preview_url: https://storage.googleapis.com/pyplots-images/plots/scatter-size-mapped/pygal/plot.png +preview_thumb: https://storage.googleapis.com/pyplots-images/plots/scatter-size-mapped/pygal/plot_thumb.png +preview_html: https://storage.googleapis.com/pyplots-images/plots/scatter-size-mapped/pygal/plot.html +quality_score: 91 +review: + strengths: + - Excellent realistic data generation with regional economic patterns (Europe higher + GDP, Africa lower GDP) + - Proper use of pygal XY chart with custom node sizes via the node dict parameter + for bubble sizing + - Well-implemented semi-transparency (opacity=0.6) for distinguishing overlapping + bubbles + - Clean code structure following KISS principles with proper seed for reproducibility + - Size legend integrated into title subtitle (Bubble Size = Population 1M to 1B+) + - Improved minimum bubble size (12) from previous attempt makes smaller populations + more visible + weaknesses: + - Grid lines are too subtle and barely visible - could use more prominent guide + styling + - Title format includes subtitle which slightly deviates from the exact spec format