Skip to content

Position stacking is computed globally instead of per-facet-panel #244

@cpsievert

Description

@cpsievert

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
Image

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions