ggplot2
ggplot2 copied to clipboard
position_dodge() doesn't properly dodge segments
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)
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()
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
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.
Is there any progress on this?