boptimden
boptimden

Reputation: 21

Putting horizontal lines on grouped boxplots

I am trying to make a boxplot with this basic code:

design=c("Red","Green","Blue")
actions=c("1","2","3","4","5","6","7","8")
proportion=(seq(1:240)+sample(1:500, 240, replace=T))/2000
df=data.frame(design, actions , proportion)

ggplot(df, aes(x=actions, y=proportion, fill=design)) + 
  geom_boxplot()+
  xlab(TeX("group"))+
  ylab("Y value")+
  ggtitle("Y values for each group stratified by color")

Producing something like this: Group boxplot

I want to add horizontal lines for "true" Y values that are different for each group.

Does anyone have any tips for doing this? I don't know how to extract the width of each group of boxes, otherwise I could use geom_segment.

Here is a MWE with a non-grouped boxplot:

dBox <- data.frame(y = rnorm(10),group="1")
dBox=rbind(dBox,data.frame(y=rnorm(10),group="2"))
dLines <- data.frame(X =c(-0.36, 0.015),
                     Y = c(0.4, -0.2),
                     Xend = c(0.-0.015, 0.36),
                     Yend=c(0.4, -0.2),
                     group = c("True", "True"),
                     color = c("black", "red"))

ggplot(dBox, aes(x=0, y=y,fill=group)) +
  geom_boxplot(outlier.shape = 1)+ 
  geom_segment(data = dLines, aes(x = X, xend = Xend, y = Y, yend = Yend),color="red",size=1.5,linetype=1) +
  theme(legend.background = element_rect(fill = "white", size = 0.1, linetype = "solid", colour = "black"))

This produces something like this: Simple boxplot with red horizontal lines for true values

However, it's difficult to make the geom_segments line up with the boxes exactly, and to then extend this to the grouped boxplot setting.

Thanks!

Upvotes: 2

Views: 1247

Answers (2)

user438383
user438383

Reputation: 6206

This can be done using a workaround with facets:

lines = data.frame(actions = 1:8, proportion=abs(rnorm(8)))

design=c("Red","Green","Blue")
actions=c("1","2","3","4","5","6","7","8")
proportion=(seq(1:240)+sample(1:500, 240, replace=T))/2000
df=data.frame(design, actions , proportion)

lines = data.frame(actions = 1:8, proportion=abs(rnorm(8)))

p = ggplot(df, aes(x=actions, y=proportion, fill=design)) + 
  geom_boxplot()+
  xlab("group")+
  ylab("Y value")+
  ggtitle("Y values for each group stratified by color") +
  facet_grid(~actions, scale='free_x') +
  theme(
    panel.spacing.x = unit(0, "lines"), 
    strip.background = element_blank(),
    strip.text.x = element_blank())

p + geom_hline(aes(yintercept = proportion), lines)

You could probably fiddle around with removing the spaces between the facets to make it look more like what you intended.

Thanks to @eugene100hickey for pointing out how to remove spacing between facets.

enter image description here

Upvotes: 2

eugene100hickey
eugene100hickey

Reputation: 391

theme(panel.spacing.x) can remove those pesky lines:

p + geom_hline(aes(yintercept = proportion), lines) +
    theme(panel.spacing.x = unit(0, "lines"))

enter image description here

Upvotes: 1

Related Questions