0

I'm trying to add errorbars and median to the plot with legends. I added the errorbars and medians but I'm failing to add the legends under the same legend (e.g color or shape) so they'll be together. I tried legend.spacing.y and other methods in this link but only with limited success. I would also like the errorbars vertically in the legend with their whiskers. This is my code:

library(tidyverse)

date <- sample(seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day"), 500,replace=TRUE)
flow <- rnorm(500)
df <- data.frame(date,flow)
monthOrder <- c('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
df$Month <- factor(format(df$date, "%b"), levels = monthOrder)

df.bar <- df %>% count(Month)

med_IQR <- function(x) {
  # Change x below to return the instructed values
  data.frame(y = median(x), # Median
             ymin = quantile(x,0.05), # 1st quartile
             ymax = quantile(x,0.95))  # 3rd quartile
}
p <- ggplot()+
  geom_bar(data=df.bar,aes(Month,n/sum(n)),stat="identity",alpha=0.7,width=0.75)+
  geom_point(data=df,aes(x=Month,y=flow/10),stat="identity",
             position=position_jitter(width=0.25),alpha=0.7,col="orangered3")+
  stat_summary(data=df,aes(x=Month,y=flow/10,shape="Median"),geom="point",fun.y = median,
               size = 2,color="blue3")+
  stat_summary(data=df,aes(x=Month,y=flow/10,color = "CI"),geom="errorbar",fun.data = med_IQR,
               width = 0.2)+
  scale_shape_manual(values=c("Median"=16))+
  scale_color_manual(values=c("CI"="blue3"))+
  guides(shape=guide_legend(title="",override.aes = list(color=c("blue3"))),
         color=guide_legend(title=""))
p
Valentin_Ștefan
  • 6,130
  • 2
  • 45
  • 68
asher
  • 174
  • 1
  • 1
  • 12
  • 1
    Possible duplicate of [Is there a way to change the spacing between legend items in ggplot2?](https://stackoverflow.com/questions/11366964/is-there-a-way-to-change-the-spacing-between-legend-items-in-ggplot2) – pogibas Dec 26 '18 at 12:37
  • @PoGibas Thanks for sharing the question. I tried the answers including Tungs which is very clear and seems to be what i was looking for but only limited success. also legend.spacing.y has a limit. I will edit the question to emphasize the errorbars placing and position. – asher Dec 26 '18 at 13:03

1 Answers1

1

For reducing the space between your legend keys, I think you were pointed already in the right direction. Have you tried also negative values like this?

p <- p + theme(legend.spacing.y = unit(-1,"cm"))

enter image description here

If I understand correctly, you need to flip the line depicting the error bars. That can be done in a hackish way with the grid package functionality:

library(grid)

# Transform to a grob tree
g <- ggplotGrob(p)

# Helpful to check the structure of the grob Tree
View(g$grobs)

# Edit the specific line from the legend key
g$grobs[[15]][["grobs"]][[1]][["grobs"]][[4]][["x0"]] <- unit(0.5, "npc")
g$grobs[[15]][["grobs"]][[1]][["grobs"]][[4]][["y0"]] <- unit(0.1, "npc")
g$grobs[[15]][["grobs"]][[1]][["grobs"]][[4]][["x1"]] <- unit(0.5, "npc")
g$grobs[[15]][["grobs"]][[1]][["grobs"]][[4]][["y1"]] <- unit(0.9, "npc")

# Draw the edited grob tree
grid.newpage(); grid.draw(g)

enter image description here

If you want to know more about the grid package and do further fine-grained edits, check browseVignettes(package="grid") and/or check the author's page with documentation here. Debugging grid Graphics by Paul Murrell (author of grid) and Velvet Ly is also useful and good as a intro as well.

Saving the edited grob tree works with the usual ggsave: ggsave(plot = g, filename = "edited-plot.png")

Valentin_Ștefan
  • 6,130
  • 2
  • 45
  • 68
  • Thanks. This works fine. Indeed I didn't try a minus value. I will have a look at the grid package. – asher Dec 27 '18 at 07:55