Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split geom_point points along x axis by group

Tags:

r

ggplot2

This is driving me up the wall, and I'm sure I am missing something simple. Any help would be appreciated.

I want the red and blue points to be separated, with each set over the corresponding boxplot as in second image, but with a numeric x axis as in the first image.

df <- data.frame(x = rep(c(1, 2, 10), each = 20), 
               g = rep(c("A", "B"), times = 30), 
               y = c(rnorm(60, 0, 1)))

# OK - boxplot by x and g
  ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
    geom_boxplot() 

# Not OK. The dots are only grouped by x, not g  
  ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
    geom_point() 

# I want the points to correctly overlay the boxplots
  ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
    geom_boxplot(alpha = 0.1) +
    geom_point()

enter image description here

(I have fixed it by faceting on x, but I want the axis as numeric to reflect the correct scaling)

   ggplot(df, aes(y = y, x = g, fill = g, color = g, group = interaction(x, g))) +
     geom_boxplot(alpha = 0.1) +
     geom_point() +
     facet_wrap(~x)

enter image description here

like image 485
D L Dahly Avatar asked Oct 27 '17 19:10

D L Dahly


Video Answer


3 Answers

You can use position=position_dodge(...) in geom_point.

ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
  geom_boxplot(alpha = 0.1, width=0.75) +
  geom_point(position = position_dodge(width=0.75))

I also defined a width for geom_boxplot to match the position_dodge width in geom_point. enter image description here

like image 120
Djork Avatar answered Oct 21 '22 03:10

Djork


In case you want jitter as well, you can use position_jitterdodge.

 ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
       geom_boxplot(alpha = 0.1, width=0.75) +
       geom_point(position = position_jitterdodge(jitter.width=0.85))
like image 27
timcdlucas Avatar answered Oct 21 '22 03:10

timcdlucas


If using geom_beeswarm, you can use the dodge.width option

 library(ggbeeswarm)

 ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
    geom_boxplot(alpha = 0.1, width = 0.75) +
    geom_beeswarm(dodge.width = 0.75)

enter image description here

like image 20
D L Dahly Avatar answered Oct 21 '22 03:10

D L Dahly