ggplot2 icon indicating copy to clipboard operation
ggplot2 copied to clipboard

position_dodge() doesn't properly dodge segments

Open clauswilke opened this issue 5 years ago • 3 comments

See related discussion on SO. position_dodge() doesn't dodge the xend aesthetic and as a consequence segments can't be dodged. In the reprex below, the desired effect is to connect the points of identical color within each group.

library(tidyverse)

set.seed(1234)

df <- tibble(
    group = rep(letters[1:3], each = 2),
    subgroup = rep(c("A", "B"), 3)
  ) %>%
  mutate(
    start = rpois(6, 10),
    end = start + rpois(6, 3)
  )

ggplot(df) +
  geom_point(
    aes(group, start, color = subgroup),
    position = position_dodge(width = 1)
  ) +
  geom_point(
    aes(group, end, color = subgroup),
    position = position_dodge(width = 1)
  ) +
  geom_segment(
    aes(x = group, xend = group, y = start, yend = end, color = subgroup),
    position = position_dodge(width = 1)
  ) +
  coord_flip()

Created on 2019-11-08 by the reprex package (v0.3.0)

clauswilke avatar Nov 08 '19 07:11 clauswilke

If you use position_nudge() instead of position_dodge(), both the x and xend values for the segment are moved, allowing the dots to connect. I just can't figure out how position_nudge() is able to work with xend, but position_dodge() is not. It looks like position_dodge() is pulling the values from df$x, so it's missing xend. I'm not sure how position_nudge() is pulling both.

library(tidyverse)

set.seed(1234)

df <- tibble(
    group = rep(letters[1:3], each = 2),
    subgroup = rep(c("A", "B"), 3)
  ) %>%
  mutate(
    start = rpois(6, 10),
    end = start + rpois(6, 3)
  )

ggplot(df) +
  geom_point(
    aes(group, start, color = subgroup),
    position = position_nudge(x = 0.5, y = 0)
  ) +
  geom_point(
    aes(group, end, color = subgroup),
    position = position_nudge(x = 0.5, y = 0)
  ) +
  geom_segment(
    aes(x = group, xend = group, y = start, yend = end, color = subgroup),
    position = position_nudge(x = 0.5, y = 0)
  ) +
  coord_flip()

brwheeler avatar Nov 11 '19 04:11 brwheeler

There is a bit of uncertainty with how segments should be interpreted when dodging. Should they behave like points and just have xend follow along, or should they be interpreted as ranges so that xmin = pmin(x, xend), and xmax = pmax(x, xend) with a width that can be derived from it?

I don't have strong feelings one way or the other

thomasp85 avatar Apr 20 '21 10:04 thomasp85

A way that I've gotten around this is by using geom_bar instead, and then just making the width very narrow, so that it looks like a segment.

markhwhiteii avatar Sep 13 '21 20:09 markhwhiteii

Is there any progress on this?

MxNl avatar Oct 27 '22 09:10 MxNl