Home > Mobile >  Adding gaps at specific intervals on the x-axis in a ggplot bar graph
Adding gaps at specific intervals on the x-axis in a ggplot bar graph

Time:02-01

I have a mocked up data set here that I would like to introduce larger gaps into on the x-axis at particular intervals.

I would like these gaps to be larger specifically between the day groups.

In this case, the would be a larger gap after the first 2 groups, then after the second 2 groupings, then after the next 3 groups, so on...

Here is my current output: Current graph output

Here is my code:

library("ggplot2")
library("grid")
library("dplyr")

df <- data.frame(
  day = c(rep(11, 6), rep(12, 6), rep(23, 9), rep(31, 9), rep(47, 9)),
  hz = c(rep(1, 3), rep(2, 3), rep(1, 3), rep(2, 3), rep(1, 3), rep(2, 3), rep(4, 3) , rep(1, 3), rep(2, 3), rep(4, 3), rep(1, 3), rep(2, 3), rep(4, 3)),
  ft = c(38,42,45,28,30,45,38,41,45,25,30,45,45,43,50,30,28,48,30,33,40,45,41,47,38,35,43,30,32,50,46,40,50,38,30,40,30,28,40),
  sp = c(rep(c("Ctrl", "Absrc", "Ab42"), 13))
)

se <- function(a) sd(a)/sqrt(length(a))

g1 <- ggplot(df, aes(x=interaction(hz, day), y=ft, group=desc(sp), fill=sp))  
  geom_bar(position=position_dodge(), stat="identity")  
  geom_errorbar(aes(ymax=ft se(ft), ymin=ft-se(ft)), position=position_dodge(0.9), width=0.5)  
  coord_cartesian(ylim=c(0, 60))  
  annotate("text", x=c(1.5, 3.5, 6, 9, 12), y=-6, label=c("day 11", "day 12", "day 23", "day 31", "day 47"))  
  annotate("text", x=1:13, y=-3, label=c(rep(c("1 hz", "2hz"), 2), rep(c("1 hz", "2 hz", "4hz"), 3)))  
  theme_classic()   
  theme(plot.margin=unit(c(1,1,4,1), "lines"),
        axis.title.x= element_blank(),
        axis.text.x=element_blank())   
  scale_fill_discrete(breaks=c("Ctrl", "Absrc", "Ab42"))   
  scale_fill_grey()   
  scale_y_continuous(expand=c(0,0))


g2 <- ggplot_gtable(ggplot_build(g1))
g2$layout$clip[g2$layout$name == "panel"] <- "off"
grid.draw(g2)

ggsave(file="graph.svg", plot=g2)

CodePudding user response:

One option would be to use facetting which also allows to add the labels for the days without the need of the annotate hack. And in case you don't want the gaps on the axis you could set the panel spacing to zero and instead increase the expansion of the x scale to add some more space between the panels:

library(ggplot2)

ggplot(df, aes(x = interaction(hz, day), y = ft, group = desc(sp), fill = sp))  
  geom_bar(position = position_dodge(), stat = "identity")  
  geom_errorbar(aes(ymax = ft   se(ft), ymin = ft - se(ft)), position = position_dodge(0.9), width = 0.5)  
  scale_x_discrete(labels = ~paste(substr(.x, 1, 1), "hz"))  
  facet_grid(.~day, switch = "x", scales = "free_x", space = "free_x",
             labeller = labeller(day = ~ paste("day", .x)))  
  coord_cartesian(ylim = c(0, 60), clip = "off")  
  theme_classic()  
  theme(
    plot.margin = unit(c(1, 1, 1, 1), "lines"),
    axis.title.x = element_blank(),
    strip.background.x = element_blank(),
    strip.placement = "outside",
    #panel.spacing.x = unit(0, "pt")
  )  
  scale_fill_grey(breaks = c("Ctrl", "Absrc", "Ab42"))  
  scale_y_continuous(expand = c(0, 0))

enter image description here

  • Related