Skip to content

feat: add scatter-basic implementation (9 libraries)#510

Merged
MarkusNeusinger merged 19 commits intomainfrom
plot/scatter-basic
Dec 7, 2025
Merged

feat: add scatter-basic implementation (9 libraries)#510
MarkusNeusinger merged 19 commits intomainfrom
plot/scatter-basic

Conversation

@MarkusNeusinger
Copy link
Copy Markdown
Owner

Summary

Adds scatter-basic plot implementation.

Libraries

  • Merged: 9 (all libraries)
  • Not Feasible: 0

Links


🤖 Auto-generated by pyplots CI

claude bot and others added 19 commits December 6, 2025 23:32
## Summary
Implements `scatter-basic` for **matplotlib** library.

**Parent Issue:** #207
**Sub-Issue:** #231
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/matplotlib/scatter/scatter-basic/default.py`

## Changes
- Simplified implementation to follow KISS style guide
(plot-generator.md)
- Uses sequential script structure: imports → data → plot → save
- No functions, classes, or type hints per guidelines
- Follows default-style-guide.md for colors (Python Blue #306998) and
dimensions (16:9 aspect)
- Proper font sizes for 4800x2700px output

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **altair** library.

- Basic scatter plot with 100 sample data points showing positive
correlation
- Python Blue color (#306998) with appropriate opacity
- Proper axis labels and chart title
- Output: 4800x2700px (via scale_factor=3.0)
- Includes tooltips for interactivity

**Parent Issue:** #207
**Sub-Issue:** #262
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/altair/point/scatter-basic/default.py`

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **seaborn** library.

**Parent Issue:** #207
**Sub-Issue:** #241
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/seaborn/scatterplot/scatter-basic/default.py`

## Changes
- Simplified implementation following KISS principle (no functions, no
classes, no type hints)
- Uses sequential script structure matching matplotlib gallery examples
- Python Blue (#306998) color from default style guide
- Proper figure size (16x9) with appropriate font sizes (20pt for
labels/title, 16pt for ticks)
- Grid with subtle alpha (0.3) for visual clarity

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **plotnine** library.

**Parent Issue:** #207
**Sub-Issue:** #268
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/plotnine/point/scatter-basic/default.py`

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **plotly** library.

**Parent Issue:** #207
**Sub-Issue:** #248
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/plotly/scatter/scatter-basic/default.py`

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **pygal** library.

**Parent Issue:** #207
**Sub-Issue:** #272
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/pygal/xy/scatter-basic/default.py`

## Details
- Uses pygal's XY chart type for scatter plot visualization
- Follows pyplots color palette (Python Blue #306998)
- Generates 100 correlated random data points
- Output: 4800 × 2700 px PNG image
- Grid guides enabled for visual clarity

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **highcharts** library.

**Parent Issue:** #207
**Sub-Issue:** #275
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/highcharts/scatter/scatter-basic/default.py`

## Details
- Uses highcharts-core Python library with Selenium for PNG export
- Follows pyplots style guide with Python Blue (#306998) color
- Target image dimensions: 4800 × 2700 px
- Generates 100 random data points with clear correlation pattern
- Clean axis labels and title with appropriate font sizes

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **letsplot** library.

**Parent Issue:** #207
**Sub-Issue:** #278
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/letsplot/point/scatter-basic/default.py`

### Features
- Uses lets-plot's ggplot2-style grammar of graphics
- Generates 4800 × 2700 px output (16:9 aspect ratio)
- Python Blue (#306998) color from style guide
- Proper alpha transparency for overlapping points
- Clear axis labels and title with appropriate font sizes

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **plotly** library.

**Parent Issue:** #207
**Sub-Issue:** #405
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/plotly/scatter/scatter-basic/default.py`

## Changes
- Uses `plotly.graph_objects.Scatter` with markers mode
- Python Blue (#306998) color with 0.7 opacity
- Proper font sizing for 4800x2700 output (title/axis: 40pt, ticks:
32pt)
- Clean white template with subtle grid
- Margins adjusted for label visibility

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **altair** library.

**Parent Issue:** #207
**Sub-Issue:** #406
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/altair/point/scatter-basic/default.py`

## Changes
- KISS-style scatter plot implementation
- Uses Python Blue color (#306998)
- Proper axis labels (X Value, Y Value) and title
- 100 random data points with correlation pattern
- Output: 4800x2700px PNG (via scale_factor=3.0)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **highcharts** library.

**Parent Issue:** #207
**Sub-Issue:** #409
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/highcharts/scatter/scatter-basic/default.py`

## Changes
- Basic scatter plot with 100 random data points showing positive
correlation
- Python Blue (#306998) markers for data points
- X and Y axis labels with clear font sizes (40px)
- Grid lines for readability
- Chart dimensions: 4800 x 2700 px
- Uses element screenshot for accurate PNG capture

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **plotnine** library.

**Parent Issue:** #207
**Sub-Issue:** #407
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/plotnine/point/scatter-basic/default.py`

## Changes
- Added typography settings (plot_title, axis_title, axis_text) for
proper font sizes at 4800x2700px
- Uses Python Blue (#306998) from style guide
- Generates 4800x2700px PNG output at 300 DPI

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **letsplot** library.

**Parent Issue:** #207
**Sub-Issue:** #410
**Base Branch:** `plot/scatter-basic`
**Attempt:** 2/3

## Implementation
- `plots/letsplot/point/scatter-basic/default.py`

## Features
- Uses lets-plot ggplot2-style grammar of graphics
- Python Blue (#306998) color for data points
- Proper sizing (4800x2700px via scale=3)
- theme_minimal() with custom font sizes for readability
- Follows all quality criteria and style guide requirements

## Note
Previous PR #449 was closed due to transient GitHub Actions
infrastructure timeout (unrelated to code).

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **matplotlib** library.

**Parent Issue:** #207
**Sub-Issue:** #319
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/matplotlib/scatter/scatter-basic/default.py`

## Details
- 100 random data points with linear correlation pattern
- Python Blue (#306998) markers with alpha transparency
- Font sizes optimized for 4800x2700 output (20pt labels, 16pt ticks)
- Grid enabled with subtle alpha for visual clarity
- Marker size increased to 80 for better visibility at high resolution

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **highcharts** library.

**Parent Issue:** #207
**Sub-Issue:** #442
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/highcharts/scatter/scatter-basic/default.py`

## Details
- Basic scatter plot with 100 random data points showing positive
correlation
- Uses Python Blue (#306998) color for data points (from style guide)
- X and Y axis labels with readable font sizes
- Grid lines at 10% opacity for subtle visual guidance
- Chart dimensions: exactly 4800 x 2700 px (16:9 aspect ratio)
- Uses PIL to crop screenshot to exact dimensions required
- Headless Chrome + Selenium for PNG export
- Inline Highcharts JS embedding (required for headless Chrome)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **bokeh** library.

**Parent Issue:** #207
**Sub-Issue:** #255
**Base Branch:** `plot/scatter-basic`
**Attempt:** 2/3

## Implementation
- `plots/bokeh/scatter/scatter-basic/default.py`

## Details
- Uses `bokeh.plotting.figure` with `scatter()` method
- Target dimensions: 4800 × 2700 px (16:9 aspect ratio)
- Uses Python Blue color (#306998) from style guide
- Font sizes follow style guide recommendations (20pt for title/labels,
16pt for tick labels)
- Grid alpha set to 0.3 for subtle grid lines
- Exports as PNG using `export_png()`

## ⚠️ CI Blocker - Workflow Change Required

The CI tests are failing because the workflow needs to setup Chrome for
bokeh (just like highcharts). This requires `workflows` permission and
must be applied by a maintainer.

**Error:** `RuntimeError: To use bokeh.io image export functions you
need selenium`

**Fix required in `.github/workflows/ci-plottest.yml`:**

```yaml
# Change line 69-70 from:
- name: Setup Chrome for Highcharts
  if: steps.detect_libs.outputs.has_plots == 'true' && contains(steps.detect_libs.outputs.libraries, 'highcharts')

# To:
- name: Setup Chrome for Bokeh/Highcharts
  if: steps.detect_libs.outputs.has_plots == 'true' && (contains(steps.detect_libs.outputs.libraries, 'bokeh') || contains(steps.detect_libs.outputs.libraries, 'highcharts'))
```

**Note:** The implementation itself is correct and works locally. The
`lib-bokeh` extras in `pyproject.toml` already include selenium and
webdriver-manager.

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **altair** library.

- Basic scatter plot with 100 random data points showing correlation
- Uses Python Blue (#306998) from style guide
- Configured for 4800x2700px output (1600x900 with scale_factor=3)
- Includes tooltips for interactivity
- Proper axis labels, title, and font sizing

**Parent Issue:** #207
**Sub-Issue:** #441
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/altair/point/scatter-basic/default.py`

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
Implements `scatter-basic` for **highcharts** library.

**Parent Issue:** #207
**Sub-Issue:** #491
**Base Branch:** `plot/scatter-basic`
**Attempt:** 1/3

## Implementation
- `plots/highcharts/scatter/scatter-basic/default.py`

## Changes
- Uses spec example data (8 data points) for the scatter plot
- Screenshots the chart container element directly for exact 4800x2700
dimensions
- Removed PIL dependency by using Selenium element screenshot
- Adjusted font sizes for better readability at high resolution (60px
title, 48px axis labels, 40px tick labels)
- Uses Python Blue (#306998) color from the style guide

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Copilot AI review requested due to automatic review settings December 7, 2025 21:14
@MarkusNeusinger MarkusNeusinger merged commit 402d7dc into main Dec 7, 2025
@MarkusNeusinger MarkusNeusinger deleted the plot/scatter-basic branch December 7, 2025 21:14
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 7, 2025

✅ Plot Tests Passed

Python 3.13 (required): passed

Compatibility: 3.12 3.13

Note: Only Python 3.13 is required to pass. Python 3.12 is tested for compatibility.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the scatter-basic specification across all 9 supported visualization libraries (matplotlib, seaborn, plotly, bokeh, altair, plotnine, pygal, highcharts, lets-plot). The implementation follows the project's specification-first design pattern, where a single library-agnostic spec in specs/scatter-basic.md generates corresponding implementations in each library's directory structure. All implementations generate scatter plots showing the relationship between two continuous variables with consistent styling (Python Blue #306998 color, 16:9 aspect ratio at 4800×2700px).

Key Changes:

  • Replaces function-based matplotlib/seaborn implementations with simpler KISS-style scripts
  • Adds 7 new library implementations (plotly, bokeh, altair, plotnine, pygal, highcharts, lets-plot)
  • All implementations follow the modern gallery-style pattern: imports → data → plot → save

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
plots/matplotlib/scatter/scatter-basic/default.py Simplified from function-based to script-based implementation; data generation parameters differ from other libraries
plots/seaborn/scatterplot/scatter-basic/default.py Simplified from function-based to script-based implementation with consistent styling
plots/plotly/scatter/scatter-basic/default.py New implementation using plotly graph objects with proper 4800×2700px output
plots/bokeh/scatter/scatter-basic/default.py New implementation using bokeh scatter with export_png
plots/altair/point/scatter-basic/default.py New declarative implementation with scale_factor for proper dimensions
plots/plotnine/point/scatter-basic/default.py New ggplot2-style implementation following plotnine conventions
plots/pygal/xy/scatter-basic/default.py New SVG-based implementation with custom styling
plots/highcharts/scatter/scatter-basic/default.py New implementation using Selenium for rendering; uses different data than other libraries and downloads external JS
plots/letsplot/point/scatter-basic/default.py New JetBrains lets-plot implementation with ggplot2 grammar

n_points = 500
# Data
np.random.seed(42)
x = np.random.randn(100) * 2 + 5
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data generation is inconsistent with other libraries. Most implementations use x = np.random.randn(100) * 2 + 10, but this one uses + 5 instead of + 10. This will result in different x-axis ranges and make visual comparisons across libraries inconsistent.

Suggested change
x = np.random.randn(100) * 2 + 5
x = np.random.randn(100) * 2 + 10

Copilot uses AI. Check for mistakes.
# Data
np.random.seed(42)
x = np.random.randn(100) * 2 + 5
y = x * 0.8 + np.random.randn(100) * 1.5
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data generation is inconsistent with other libraries. The y-value calculation uses * 1.5 for the random component, while most other implementations use * 2. This creates different data distributions and visual appearances across libraries.

Suggested change
y = x * 0.8 + np.random.randn(100) * 1.5
y = x * 0.8 + np.random.randn(100) * 2

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +20
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [2.1, 4.3, 3.2, 5.8, 4.9, 7.2, 6.1, 8.5]
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard-coded data is inconsistent with all other implementations. Other libraries generate 100 random points with correlation, but this uses only 8 manually specified points. This creates a significantly different visualization and doesn't properly demonstrate a scatter plot's utility for many data points. Use the same data generation pattern as other libraries: np.random.seed(42), x = np.random.randn(100) * 2 + 10, y = x * 0.8 + np.random.randn(100) * 2.

Copilot uses AI. Check for mistakes.
Comment on lines +56 to +60
# Download Highcharts JS for inline embedding
highcharts_url = "https://code.highcharts.com/highcharts.js"
with urllib.request.urlopen(highcharts_url, timeout=30) as response:
highcharts_js = response.read().decode("utf-8")

Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Downloading external JavaScript from an untrusted source without integrity verification poses a security risk. If code.highcharts.com is compromised, malicious code could be executed. Consider either: (1) bundling the Highcharts library with the project, (2) verifying the downloaded content's hash against a known good value, or (3) adding a comment acknowledging this trade-off if it's an intentional design decision.

Suggested change
# Download Highcharts JS for inline embedding
highcharts_url = "https://code.highcharts.com/highcharts.js"
with urllib.request.urlopen(highcharts_url, timeout=30) as response:
highcharts_js = response.read().decode("utf-8")
# Use bundled Highcharts JS for inline embedding to avoid runtime download and supply chain risk.
# See: https://github.com/highcharts/highcharts for official source.
highcharts_js_path = Path(__file__).parent.parent / "vendor" / "highcharts.js"
with open(highcharts_js_path, "r", encoding="utf-8") as f:
highcharts_js = f.read()

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants