Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

position_dodgev causes error in order of connecting points in geom_line

Tags:

r

ggplot2

I want to plot over a timecourse x with y values that are often repeated (integer scores 1-4) and I want to visualize many subjects at once.

Because there is so much overlap, a vertical position dodge would be ideal, such as position_dodgev from ggstance package. However, when I try to connect the dots with geom_line, the order of the connection gets messed up and is connected based on y values and not x values.

I tried a coordinate flip work-around which was not successful. And replacing geom_line with geom_path (making sure it was ordered on the x scale) also did not work.

Here is a reproducible example:

#data
df<-tibble(x=c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5),
           y=c(1,2,3,7,7,1,2,3,7,7,2,1,6,7,7),
           group=c('a','a','a','a','a','b','b','b','b','b','c','c','c','c','c'))


#horizontal dodge masks groups
ggplot(df, aes(x=x, y=y,col=group,group=group)) +
  geom_point(position=position_dodge(width=0.3))+
  geom_line(position=position_dodge(width=0.3))


#line connection error with vertical dodge
library(ggstance)
ggplot(df, aes(x=x, y=y,col=group,group=group)) +
  geom_point(position=position_dodgev(height=0.3))+
  geom_line(position=position_dodgev(height=0.3))

Horizontal dodge works as expected but does not allow visualization of all the overlapped groups in a stretch of repeated y values. Vertical dodge from ggstance connected the dots in group c in the wrong order.

enter image description here

like image 849
Keirnan Willett Avatar asked Jan 26 '26 08:01

Keirnan Willett


1 Answers

I am not sure what exactly causes the issue. Knowing that position_dodge is not intended to be used with geoms and it's been called a bug, I am surprised and not at the same time about this issue.

But in any case, I found a workaround by disassembling the plot using ggplot_build, rearranging the points for geom_line within that object and then reassembling the plot again; look below:

g <- ggplot(df, aes(x=x, y=y,col=group,group=group)) +
  geom_point(position=position_dodgev(height=0.3)) +
  geom_line(position=position_dodgev(height=0.3))

gg <- ggplot_build(g)

# -- look at gg$data to understand following lines --
#gg$data[[2]]: data associated with geom_line as it is the 2nd geom
#c(1,2) & c(2,1): I have $group==3 ...
# ... so just need to flip 1st and 2nd datapoints within that group 

gg$data[[2]][gg$data[[2]]$group==3,][c(1,2),] <- 
gg$data[[2]][gg$data[[2]]$group==3,][c(2,1),]

gt <- ggplot_gtable(gg)

plot(gt)

              enter image description here

like image 58
M-- Avatar answered Jan 27 '26 23:01

M--



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!