Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I dodge / combine both geom_point and geom_boxplot with two factors

I'm looking to add point data so that is sits adjacent to a box in a boxplot. When I run the below example, the point data does not separate for each fill factor. Is there a way to add point data that corresponds to the box when plotting 2 factors in a boxplot? Can this also be added so it is to the left of the box rather than on top of it?

Group<-c("A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B")
Value<-c(2,1,6,4,2,5,3,6,8,1,10,2,2,3,4,6)
Round<-c("Round 1","Round 1","Round 1","Round 1","Round 2","Round 2","Round 2","Round 2",
     "Round 1","Round 1","Round 1","Round 1","Round 2","Round 2","Round 2","Round 2")
data<-as.data.frame(cbind(Group,Value,Round))
data$Round<-as.factor(data$Round)
data$Group<-as.factor(data$Group)
data$Value<-as.numeric(data$Value)
str(data)

ggplot(data,aes(Group,Value,fill=Round))+
 geom_point(aes(colour=Round))+
 geom_boxplot(width=0.5,position = position_dodge(width=0.7))+
 labs(fill= "Round",x="Group",y="Value")

enter image description here

like image 326
Kelly James Avatar asked Jan 22 '26 22:01

Kelly James


1 Answers

As Quinten says, one would normally use position_dodge here. However, you can't do this if you want the points to sit just to the left of the boxes, since you would need to nudge and dodge at the same time, which isn't currently an option. Instead, you can nudge the groups in two layers:

ggplot(data,aes(Group, Value, fill = Round)) +
 Map(\(r, d) geom_point(aes(colour = Round), subset(data, Round == r),
    position = position_nudge(x=d)), r = levels(data$Round), d = c(-0.33,0.02)) +
 geom_boxplot(width = 0.5, position = position_dodge(width = 0.7))

enter image description here

To have your points and boxes in the same color, use shape = 21 inside geom_point and remove the color = Round aesthetic mapping:

ggplot(data,aes(Group, Value, fill = Round)) +
  Map(function(r, d) geom_point(data = subset(data, Round == r),
      shape = 21, position = position_nudge(x = d), size = 2), 
      r = levels(data$Round), d = c(-0.33, 0.02)) +
  geom_boxplot(width = 0.5, position = position_dodge(width = 0.7)) +
  scale_fill_manual(values=c("#6699FF","#FFFFFF")) +
  theme_gray(base_size = 16)

enter image description here

Or, if you don't want the points outlined (but then the white points are difficult to see)

ggplot(data,aes(Group, Value, fill = Round)) +
  Map(function(r, d) geom_point(aes(color = Round), 
                       data = subset(data, Round == r),
                       position = position_nudge(x = d), size = 2), 
      r = levels(data$Round), d = c(-0.33, 0.02)) +
  geom_boxplot(width = 0.5, position = position_dodge(width = 0.7)) +
  scale_fill_manual(values=c("#6699FF","#FFFFFF")) +
  scale_color_manual(values=c("#6699FF","#FFFFFF")) +
  theme_gray(base_size = 16)

enter image description here

like image 55
Allan Cameron Avatar answered Jan 25 '26 14:01

Allan Cameron