Skip to content

Infer dodge grouping from fill in position_jitterdodge()#6826

Open
Jesssullivan wants to merge 2 commits intotidyverse:mainfrom
Jesssullivan:jitterdodge-smart-default
Open

Infer dodge grouping from fill in position_jitterdodge()#6826
Jesssullivan wants to merge 2 commits intotidyverse:mainfrom
Jesssullivan:jitterdodge-smart-default

Conversation

@Jesssullivan
Copy link
Copy Markdown

@Jesssullivan Jesssullivan commented Mar 29, 2026

Infer dodge grouping from fill in position_jitterdodge()

Closes #6824.

Motivation

position_jitterdodge() is documented as "primarily used for aligning points generated through geom_point() with dodged boxplots (e.g., a geom_boxplot() with a fill aesthetic supplied)." However, the function currently derives dodge grouping from the full implicit group interaction, which includes every discrete aesthetic in the layer — not just fill. Adding colour, shape, or linetype silently breaks the alignment this function is designed to provide.

# Points misalign because group = cyl x am x vs, but boxplot dodges by cyl x am
ggplot(mtcars, aes(factor(cyl), mpg, fill = factor(am))) +
  geom_boxplot(outlier.shape = NA) +
  geom_point(aes(colour = factor(vs)),
             position = position_jitterdodge(seed = 1))

Approach

Since this function exists specifically for boxplot+point alignment, and boxplots dodge by fill, the dodge grouping should derive from fill when available.

A 6-line unexported helper (jitterdodge_dodge_group) checks whether fill is present and discrete, returning either a fill-based group or falling back to the standard group. Three methods (setup_params, setup_data, compute_panel) use this helper to temporarily swap the group for dodging, then restore the original group for downstream use. No new parameters are added.

Note on existing behaviour

We understand that ggplot2 is a mature package and that PRs changing existing behaviour require careful consideration. This change only affects the case where the current output is visually incorrect:

Scenario Before After Change?
fill only Dodge by fill Dodge by fill Identical
fill + colour Dodge by fill x colour Dodge by fill Fix
No fill Dodge by group Dodge by group Identical
Continuous fill Dodge by group Dodge by group Identical

The only behaviour change is in the case where the current result contradicts the function's documented purpose. Users who need the old grouping can use aes(group = interaction(fill, colour)) explicitly.

Changes

  • R/position-jitterdodge.R: jitterdodge_dodge_group() helper + modifications to setup_params, setup_data, compute_panel
  • R/position-jitterdodge.R: New @section Dodge grouping: documenting the inference and fallback
  • tests/testthat/test-position-jitterdodge.R: 5 new tests (alignment, backward compat, no-fill fallback, continuous-fill fallback, existing preserve tests still pass)
  • NEWS.md: Entry added

Checklist

  • Motivation described above and in NEWS entry (@Jesssullivan, #6824)
  • Only related changes (single concern: fill-based dodge inference)
  • Tidyverse style — follows existing patterns, reuses id(), is_discrete()
  • roxygen2 docs updated, devtools::document() run
  • Unit tests added (5 new, all passing; 22 position-dodge regression tests also pass)
  • Visual tests — N/A
  • Minimal example added to @examples

Current behaviour
Post fixed default behaviour

Jesssullivan and others added 2 commits March 27, 2026 17:36
position_jitterdodge() now derives dodge grouping from the fill
aesthetic when present and discrete, rather than from the full
implicit group interaction. This ensures points align correctly
with dodged boxplots even when additional discrete aesthetics
like colour are mapped in the point layer.

When fill is absent or continuous, behaviour falls back to the
standard group aesthetic, preserving backward compatibility.
@Jesssullivan
Copy link
Copy Markdown
Author

FWIW, I prefer this inference solution to retroactive documentation route Draft PR - 6825, keen to hear others thoughts @krosepulham 👀

@Jesssullivan Jesssullivan marked this pull request as ready for review March 29, 2026 02:42
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.

position_jitterdodge() misaligns points when additional discrete aesthetics are mapped

1 participant