asher
asher

Reputation: 304

ggplot - how to adjust spacing between legend items and edit legend symbols

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

Upvotes: 0

Views: 505

Answers (1)

Valentin_Ștefan
Valentin_Ștefan

Reputation: 6416

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")

Upvotes: 1

Related Questions