Skip to content

chore(r): render on R 4.6.1 with ggplot2 4.0.3 - #12242

Merged
MarkusNeusinger merged 4 commits into
mainfrom
chore/r-4.6-ggplot2-4
Oct 23, 2026
Merged

MarkusNeusinger merged 4 commits into
mainfrom
chore/r-4.6-ggplot2-4

Conversation

@MarkusNeusinger

@MarkusNeusinger MarkusNeusinger commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Bumps the shared R setup action to R 4.6.1 and the Posit Package Manager snapshot to 2026-10-20, which moves ggplot2 from 3.5.1 to 4.0.3. All 42 packages (the list plus dependencies) install as noble binaries for R 4.6.1 from that snapshot.
  • Adds a "ggplot2 4.0 notes" section and an **API level:** ggplot2 4. line to prompts/library/ggplot2.md. The displayed versions follow the pins since refactor: derive library versions from pins, install from uv.lock #12240: the setup-r note # Snapshot 2026-10-20 ships ggplot2 4.0.3. and the r-version default give ggplot2 4.0.3 and R 4.6, and core/constants.py is unchanged.
  • Changes no plots/ file. Catalogue images stay as rendered until an implementation is regenerated.

Rebased on #12240

The branch is rebased on main after #12240. core/constants.py keeps main's version-free entries, and the setup-r action carries #12240's snapshot-note paragraph with the new date and version. tests/unit/core/test_version_sources.py passes, including the ggplot2 API level check, and pinned_versions() returns ggplot2 4.0.3 and R 4.6 with no errors.

Plan

N/A

Before and after renders

Both environments are Ubuntu 24.04 containers built like the action: R from the Posit builds through rig (what r-lib/actions/setup-r installs), the action's apt list plus fonts-dejavu-core and fonts-liberation, and the action's install.packages() call against the snapshot with the binary user agent. Each implementation ran the way impl-generate runs it: cd plots/<spec>/implementations/r && ANYPLOT_THEME=<light|dark> Rscript ggplot2.R. All 325 implementations ran, so no sample was needed.

Before After
R 4.4.1 4.6.1
Snapshot 2025-01-15 2026-10-20
ggplot2 3.5.1 4.0.3
ragg, systemfonts, textshaping 1.3.3, 1.1.0, 0.4.1 1.5.2, 1.3.2, 1.0.5
scales, patchwork, dplyr 1.3.0, 1.3.0, 1.1.4 1.4.0, 1.3.2, 1.2.1
Renders (325 specs, 2 themes) 650 ok, 0 failed 650 ok, 0 failed
Wall time, 16 in parallel 95 s 101 s
Specs with deprecation warnings 0 15

Pixel comparison of the 650 pairs (every pair has the same size):

Class Renders Specs
Identical 242 121 (both themes)
Layout shift only 345 171
Content-level change 63 33
Failed 0 0

A changed pair counts as a layout shift when under 0.01 % of its pixels lack a colour match (per-channel tolerance 24) within a 20 px window of the other render. Every pair above that threshold was inspected by eye. Most shifts come from one 4.0 change: guide_axis() no longer reserves space for blank ticks, and theme_minimal() and theme_void() blank them, so panels grow by about 11 px per axis (2 pt at 400 dpi).

The ten largest raw diffs (share of pixels with a channel delta above 32) are all layout shifts of unchanged content: horizon-basic 14.5 %, scatter-matrix 13.9 %, psychrometric-basic 13.2 %, parallel-basic 10.5 %, scatter-pitch-events 10.2 %, parallel-categories-basic 9.3 %, indicator-ichimoku 9.2 %, scatter-embedding 9.0 %, column-stratigraphic 8.8 % and line-timeseries-rolling 7.6 %.

Content-level changes, none of them a failure:

Cause Specs Verdict
Default bin edges moved in binning stats histogram-2d, histogram-kde, histogram-basic, histogram-density, subplot-grid, scatter-marginal Default drift; different bins, still correct
Default legend order changed bubble-basic, bubble-map-geographic, map-marker-clustered, swimmer-clinical-timeline, campbell-basic, timeseries-forecast-uncertainty, indicator-macd, precision-recall, line-confidence, genome-track-multi, band-basic Default drift
theme_void() root rect now has linewidth = 0, so the legend frame disappears network-directed, donut-nested, bar-3d-categorical Default drift, visible
Rotated top-axis labels run into the title heatmap-annotated Visible defect; vjust = 0 restores the 3.5.1 layout exactly (tested)
annotate("label", label.size = 0) is ignored, so 0.25 mm borders appear spectrum-nmr Visible change
Violin quantiles computed from the data, not the density violin-basic Documented 4.0 breaking change
geom_qq_line() is now an abline across the panel qq-basic Default drift
Residual shift or antialiasing, same content count-basic, polar-scatter, line-reaction-coordinate, raincloud-basic, pictogram-basic, bar-pareto, area-stacked-percent, line-training-load-pmc, upset-basic Default drift

No implementation broke: every render succeeded, and the only new log lines are deprecation warnings and Ignoring unknown parameters: label.size.

Breaking changes handled

The new prompt section tells the generator to use linewidth/border.colour on labels instead of label.size, geom_errorbar(orientation = "y") instead of geom_errorbarh(), the part-specific line widths instead of fatten, quantiles plus quantile.linetype instead of draw_quantiles, coord_transform() and annotation_borders() instead of the renamed forms, and a two-letter facet_wrap(dir = ) instead of as.table. It also covers four silent default changes: anchor bins with boundary, give bordered rects under theme_void() an explicit linewidth, set vjust = 0 on rotated top-axis text, and fix legend order with guide_legend(order = ). Each replacement was checked in the 4.0.3 container.

First review (Gemini 3.8 Flash)

  • Adopted: the section is now called notes, so the reviewer, which also reads the file, does not take it as a scoring rubric. The facet_wrap(dir = ) line now names the layout that replaces as.table = FALSE ("lb", same panel layout, checked), and the annotation_borders() rename and plot.tag inheritance were added.
  • Rejected after checking: mgcv missing (it is a recommended package and is installed with R 4.6.1), libtiff5-dev missing on noble (the package exists there), geom_crossbar(middle.linewidth = ) unverified (it runs without a warning and is the replacement the 4.0.3 deprecation message names), and the template theme needing explicit border widths (it uses theme_minimal(), whose rect line width is non-zero).

Regeneration candidates

  • Visible change: heatmap-annotated (labels overlap the title), spectrum-nmr (unwanted label borders), network-directed, donut-nested and bar-3d-categorical (legend frame lost).
  • Deprecated API, renders fine: coefficient-confidence and bar-permutation-importance (geom_errorbarh), violin-basic (draw_quantiles), strip-basic (fatten), and label.size in line-annotated-events, bode-basic, contour-map-geographic, scatter-embedding, network-transport-static, shap-waterfall, network-force-directed, network-directed, scatter-ashby-material, ternary-basic and tree-decision.

These matter only when daily-regen or impl-repair re-renders an implementation; this PR re-renders nothing.

Pre-existing gaps, unchanged by this PR

  • The action does not install hexbin, so in an environment built from the action alone hexbin-basic and hexbin-map-geographic warn and draw no hexes, before and after.
  • The action does not install maps (map-projections, flowmap-origin-destination) or qrcode (qrcode-basic). Both containers added them as test-only extras.

These packages go to a separate task, not into this PR.

Verification gaps

The .github/actions/setup-r change has no live verification loop beyond the container run above. The first real check is the next impl-generate, impl-repair or daily-regen job on an R implementation after merge. No review-retest.yml arm is needed: the "ggplot2 4.0 notes" section is generation guidance, not a review rule, even though the review step also reads prompts/library/ggplot2.md.

Test plan

  • Rendered all 325 ggplot2 implementations in both themes in the before and after containers and compared them pixel by pixel
  • Installed every package from the 2026-10-20 snapshot as a noble binary for R 4.6.1
  • ruff check, ruff format --check, mypy, pytest tests/unit tests/integration (12,331 passed after the rebase) and the changelog check
  • After merge: the first R pipeline job installs through the action and renders both themes

@codecov

codecov Bot commented Oct 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The shared rendering environment upgrade needs human sign-off because installation and rendering through the actual GitHub Actions pipeline remain unverified.

No open issues 🎉

What changed in this PR

Updates the shared R rendering environment to R 4.6.1 and ggplot2 4.0.3, with generator guidance for changed APIs and rendering defaults. Existing catalogue images remain unchanged until regeneration.

Changes:

  • Advances the R runtime and Posit snapshot to 2026-10-20.
  • Adds ggplot2 4.0 migration guidance for generated implementations.
  • Updates displayed versions and records the upgrade, with merge coordination documented for #12240.
File Description
prompts/​library/​ggplot2.md Adds ggplot2 4.0 API and rendering guidance.
core/​constants.py Updates displayed R and ggplot2 versions.
changelog.d/​r-4.6-ggplot2-4.md Records the upgrade and catalogue impact.
.github/​actions/​setup-r/​action.yml Pins R 4.6.1 and the newer package snapshot.

Review effort: Balanced

MarkusNeusinger and others added 4 commits October 23, 2026 12:00
The shared setup-r action installs R 4.6.1 (was 4.4.1) and pins the Posit
Package Manager snapshot to 2026-10-20 (was 2025-01-15), which moves
ggplot2 from 3.5.1 to 4.0.3. Every package in the list installs as a
noble binary for R 4.6.1 from that snapshot.

All 325 ggplot2 implementations render in both themes before and after
(container run mirroring the action). The ggplot2 generator prompt gains a
"ggplot2 4.0 rules" section for the changes that render differently
without an error: label borders, binning edges, theme_void() borders,
rotated top-axis text, legend order, fatten/draw_quantiles/errorbarh
deprecations. core/constants.py shows ggplot2 4.0.3 and R 4.6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rename the section to notes so the reviewer, which also reads this file,
does not take it as a scoring rubric. Spell out the facet_wrap(dir) layout
that replaces as.table = FALSE (checked: identical panel layout), and add
the annotation_borders() rename and plot.tag inheritance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mpts

After #12240 every locked library's prompt names the major it writes against;
tests/unit/core/test_version_sources.py holds ggplot2's line to the snapshot
note in the setup-r action (4.0.3, so API level 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175hA62juZoajMcqKxWFGza
@MarkusNeusinger
MarkusNeusinger merged commit 25ecafc into main Oct 23, 2026
16 checks passed
@MarkusNeusinger
MarkusNeusinger deleted the chore/r-4.6-ggplot2-4 branch October 23, 2026 10:09
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