Skip to content

Support simultaneous stacking and dodging by different variables in geom_col #6324

Closed as not planned
@bakaburg1

Description

@bakaburg1

I'd like to propose adding support for simultaneous stacking and dodging controlled by different variables in geom_col. Currently, this common visualization need requires workarounds that are both verbose and harder to maintain.

Current Limitation

When using geom_col, we can either stack or dodge bars based on a grouping variable, but not both at the same time using different variables. This makes it difficult to create visualizations where we want to:

  1. Stack bars by one categorical variable
  2. Dodge the resulting stacks by another categorical variable

Here's a reprex with counts from surveillance data stratified by year, country and surveillance protocol

Minimal Reproducible Example

library(ggplot2)
library(dplyr)

# Sample data
df <- bind_rows(
    data.frame(
        year = rep(2016, 5),
        protocol = rep("M", 5),
        country = c("A", "B", "C", "D", "E"),
        freq = c(100, 50, 30, 40, 11)
    ),
    data.frame(
        year = rep(2016, 4),
        protocol = rep("L", 4),
        country = c("A", "B", "C", "D"),
        freq = c(23, 60, 200, 100)
    )
)

# Current workaround requires multiple geom_col calls
ggplot() +
    geom_col(
        data = df %>% filter(protocol == "M"),
        aes(x = year - .5, y = freq,
            fill = protocol, group = country),
        position = "stack",
        width = 0.4
    ) +
    geom_col(
        data = df %>% filter(protocol == "L"),
        aes(x = year + .5, y = freq,
            fill = protocol, group = country),
        position = "stack",
        width = 0.4
    )

Desired Behavior

Ideally, we would be able to specify both stacking and dodging variables in a single geom_col call, something like:

# Conceptual syntax (not working)
ggplot(df, aes(x = year, y = freq)) +
    geom_col(
        aes(fill = protocol, group = country),
        position = position_stackdodge(
            stack_by = "country",
            dodge_by = "protocol"
        )
    )

Use Cases

This functionality would be particularly useful for:

  • Comparing distributions across multiple categories
  • Visualizing nested hierarchical data
  • Creating more complex compositional charts without resorting to hacky solutions
  • Maintaining consistent spacing and positioning without manual x-axis adjustments

Benefits

  1. More intuitive API for common visualization needs
  2. Reduced code complexity
  3. Better maintainability
  4. Consistent positioning and spacing handled by ggplot2
  5. Easier integration with scales and themes

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions