-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Summary
When combining stacked bars with faceting, position stacking accumulates globally across all facet panels instead of resetting to 0 within each panel. This causes bars in later panels to "stack on top of" values from earlier panels.
Reproducible example
Using the built-in penguins dataset:
SELECT * FROM ggsql:penguins WHERE sex IS NOT NULL
VISUALISE island AS x, species AS fill
DRAW bar
FACET sex
Observed stacking values
| Facet | Island | Species | pos2end (bottom) | pos2 (top) |
|---|---|---|---|---|
| female | Biscoe | Adelie | 0.0 | 22.0 |
| female | Biscoe | Gentoo | 44.0 | 102.0 |
| male | Biscoe | Adelie | 22.0 ❌ | 44.0 |
| male | Biscoe | Gentoo | 102.0 ❌ | 163.0 |
| female | Torgersen | Adelie | 0.0 | 24.0 |
| male | Torgersen | Adelie | 24.0 ❌ | 47.0 |
Expected
Each facet panel should stack independently from 0:
| Facet | Island | Species | pos2end (bottom) | pos2 (top) |
|---|---|---|---|---|
| female | Biscoe | Adelie | 0.0 | 22.0 |
| female | Biscoe | Gentoo | 22.0 | 80.0 |
| male | Biscoe | Adelie | 0.0 ✅ | 22.0 |
| male | Biscoe | Gentoo | 22.0 ✅ | 83.0 |
(Note: the "expected" Gentoo values above are illustrative — the exact counts would differ since the current stacking also seems to use global cumulative counts rather than per-panel counts.)
Root cause
In src/plot/layer/position/stack.rs:273, the cumulative sum only partitions by the group column (x position):
col(&stack_col)
.cum_sum(false)
.over([col(&group_col)]) // ← only groups by pos1 (x), not by facet columns
.alias("__cumsum__"),It should also partition by facet columns so stacking resets within each panel. In ggplot2, position adjustments are computed per-panel (after faceting).
Inconsistency with ggplot2
In ggplot2, this works correctly because position adjustments happen per-panel:
library(ggplot2)
library(palmerpenguins)
ggplot(na.omit(penguins), aes(x = island, fill = species)) +
geom_bar() +
facet_wrap(~sex)
# Each panel stacks independently from 0