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
12 changes: 9 additions & 3 deletions .github/actions/setup-r/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ inputs:
r-version:
description: "R version to install"
required: false
default: "4.4.1"
# Bump together with the snapshot date below: Posit Package Manager serves
# noble binaries per R minor version, so a new R needs a snapshot that has them.
default: "4.6.1"

runs:
using: "composite"
Expand Down Expand Up @@ -51,13 +53,17 @@ runs:
# matches the current ubuntu-latest runner image — update if GitHub moves
# the runner OS, and bump the snapshot date deliberately.
#
# Snapshot 2025-01-15 ships ggplot2 3.5.1. The repository has no R lock
# Snapshot 2026-10-20 ships ggplot2 4.0.3. The repository has no R lock
# file, so this line stands in for one: core/library_versions.py reads
# ggplot2's version from it for the database sync, but only while its date
# is the one in the URL below. A new snapshot date fails
# tests/unit/core/test_version_sources.py until this line names the ggplot2
# version the new snapshot installs (packageVersion("ggplot2") in a run).
#
# Every package below installs from this snapshot as a noble binary for
# R 4.6.1. ggplot2 4.0 changes rendering defaults; the changes that matter
# to generated code are listed in prompts/library/ggplot2.md.
#
# dependencies is restricted to required types (Depends/Imports/LinkingTo);
# the default `NA` is identical but explicit is clearer. `TRUE` would also
# pull in Suggests (sf, Hmisc, maps, quantreg, ...) — none of which the
Expand All @@ -67,7 +73,7 @@ runs:
run: |
Rscript -e '
options(
repos = c(CRAN = "https://packagemanager.posit.co/cran/__linux__/noble/2025-01-15"),
repos = c(CRAN = "https://packagemanager.posit.co/cran/__linux__/noble/2026-10-20"),
Ncpus = parallel::detectCores()
)
install.packages(
Expand Down
10 changes: 10 additions & 0 deletions changelog.d/r-4.6-ggplot2-4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
### Changed

- **R implementations now render on R 4.6.1 with ggplot2 4.0.3.** The shared R
setup action installs R 4.6.1 and pins the Posit Package Manager snapshot to
2026-10-20 (was R 4.4.1 and 2025-01-15, ggplot2 3.5.1). The ggplot2 generator
prompt gains a "ggplot2 4.0 notes" section for the changes that render
differently without an error: label borders, binning edges, `theme_void()`
borders, rotated top-axis text and legend order. All 325 ggplot2
implementations still render in both themes; existing catalogue images stay
as they are until an implementation is regenerated. (#12242)
48 changes: 47 additions & 1 deletion prompts/library/ggplot2.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ ggplot2 is the canonical implementation of the grammar of graphics in R. This
is anyplot's first R-language entry; the file extension is **`.R`** and the
runtime is **Rscript**, not Python.

**API level:** ggplot2 4. The Posit snapshot in `.github/actions/setup-r/action.yml`
pins this major; write against its API, with the changes in "ggplot2 4.0 notes"
below, not 3.x habits.

## IMPORTANT: No Workarounds

**If ggplot2 cannot implement a plot type natively, DO NOT shell out to
Expand Down Expand Up @@ -277,7 +281,8 @@ ggsave(
## R-Specific Gotchas

- Use `linewidth =` for `geom_line()` and `element_line()` in modern ggplot2
(≥ 3.4). `size =` triggers a deprecation warning.
(≥ 3.4). `size =` triggers a deprecation warning, and on `geom_bar()` /
`geom_col()` outlines ggplot2 4.0 ignores it entirely.
- `theme()` chains compose right-to-left: a later `theme()` overrides an
earlier one. Start with `theme_minimal(base_size = ...)`, then layer
`anyplot_theme`.
Expand All @@ -288,3 +293,44 @@ ggsave(
removed in dplyr ≥ 1.0; `tibble::tibble` is the correct path.
- Avoid `print(p)` at script end — `ggsave()` already renders the plot, and an
extra `print()` opens an unused interactive device.

## ggplot2 4.0 notes

Each item below changed between ggplot2 3.5 and 4.0: the old form still runs,
but renders differently or prints a deprecation warning.

- **Label borders:** set the border width with `linewidth` (`0` for no border)
and its colour with `border.colour`. `label.size` is deprecated, and
`annotate("label", ..., label.size = 0)` is ignored outright ("Ignoring
unknown parameters"), so the label gets the default 0.25 mm border.
- **Horizontal error bars:** `geom_errorbar(aes(y = term, xmin = lo, xmax = hi),
orientation = "y", width = 0.2)`. `geom_errorbarh()` is deprecated.
- **Box, crossbar, pointrange:** `fatten` is deprecated. Style the parts
directly: `geom_boxplot(median.linewidth = , box.linewidth = ,
whisker.linewidth = )`, `geom_crossbar(middle.linewidth = )`, and the point
`size` in `geom_pointrange()`.
- **Violin quantiles:** `geom_violin(quantiles = c(0.25, 0.5, 0.75),
quantile.linetype = 1)`. `draw_quantiles` is deprecated, and quantiles are now
computed from the data rather than from the density.
- **Histograms and other binning stats:** pass `boundary` (or explicit `breaks`)
together with `binwidth` or `bins`, for example `binwidth = 5, boundary = 0`.
ggplot2 4.0 moved the default bin edges, so unanchored bins shift between
versions and rarely land on round values.
- **`theme_void()` borders:** its root `rect` now has `linewidth = 0`, so a border
such as `legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT)`
disappears. Give every bordered `element_rect()` an explicit `linewidth`.
- **Rotated axis text:** set both `hjust` and `vjust`. On a top axis
(`scale_x_discrete(position = "top")`) use `vjust = 0`; without it ggplot2 4.0
pushes the labels up into the title.
- **Several legends:** fix their order with `guides(colour = guide_legend(order
= 1), size = guide_legend(order = 2))`. The default order changed in 4.0 and is
not stable across versions.
- **Subtitle, caption and tag** inherit from `text`, no longer from `title`:
style `plot.subtitle`, `plot.caption` and `plot.tag` explicitly instead of
through `title`.
- **Renamed:** `coord_transform()` replaces `coord_trans()`, and
`annotation_borders()` replaces `borders()`.
- **Facet panel order:** `facet_wrap(as.table = )` is deprecated. Set the order
with a two-letter `dir` instead: the letters name the starting corner and the
first one the filling direction, so `dir = "lb"` starts bottom-left and fills
left to right, as `as.table = FALSE` did.
Loading