1

I have a dataframe with data for each hour of the day. Each hour of the day was categorized in a specific phase of the day.

  • 0-5 is Phase 1.
  • 6-11 is Phase 2.
  • 12-17 is Phase 3.
  • 18-23 is Phase 4.

I need to add the x-axis labels for the phase to the hour labelling

This is what I have:

enter image description here

This is what I would like to have:

enter image description here

The dataframe is quite big, so the categories "hour" and "category" phase repeat very often in the dataframe.

Please, find below the R code for the plot I have:

ggplot(data = allactivities[allactivities$wave == 1,], aes(x = ap_hour_factor,y = ap_dauer_min, group=interaction(sex,ap_hour_factor), fill = factor(sex))) +
  stat_summary(fun.y=mean, geom= "line", size=1, aes(group = sex, colour = factor(sex)), linetype = "solid") +
  stat_summary(fun.y=mean, geom="point", size=2, colour = "black", aes(group = sex), show.legend = FALSE) +
  scale_y_continuous(breaks = seq(0,60,4)) +
  coord_cartesian(ylim = c(0,60)) +
  facet_grid(ap_actCode~., labeller = as_labeller(c("0" = "Sitzen und Liegen", "1" = "Stehen", "2" = "Laufen"))) +
  xlab(label = "Uhrzeit") +
  ylab(label = "Dauer in Minuten") +
  ggtitle("Alle Aktivitäten pro Stunde in der Welle 1
          nach Geschlecht und Aktivität") +
  scale_color_manual(name = "Geschlecht",
                     values = c("indianred3","orange1", "olivedrab"),
                     labels = c("Männer", "Frauen")) +
  theme(axis.title.x = element_text(size = 16, family = "sans"),
        axis.title.y = element_text(size = 16, family = "sans"),
        axis.text.x = element_text(size = 13, family = "sans"),
        axis.text.y = element_text(size = 13, family = "sans"),
        legend.title = element_text(hjust = 0.5, size = 15, family = "sans"),
        legend.text = element_text(size = 12, family = "sans"),
        legend.background = element_rect(fill = "gray97", colour = "grey"),
        strip.background = element_rect(fill = "gray95"),
        strip.text.y = element_text(size = 12, family = "sans"),
        plot.title = element_text(hjust = 0.5, size = 19, vjust = 1.5,family = "sans"),
        panel.background = element_rect(fill = "white", linetype = "solid"),
        panel.grid.major = element_line(colour = "gray90", linetype = "solid"),
        panel.grid.minor = element_line(colour = "gray90", linetype = "blank"),
        panel.border = element_rect(colour = "gray60", fill = NA, size = 1))
lovalery
  • 4,524
  • 3
  • 14
  • 28
  • 1
    welcome to stack overflow. It is a courtesy to other users to link to other threads - clearly, you have seen the first thread to which I am linking as a duplicate, this is where your screenshot comes from. If this thread doesn't help, please explain why and don't let us re-invent everything. – tjebo Feb 01 '22 at 20:52

1 Answers1

1

I'm pretty sure there isn't a simple built-in way to do this in ggplot2, but there might be a package (like ggh4x) which adds this, or you could hack it like below. In this case I use coord_cartesian to specify what range of data I want to be in the plot area, but by using clip = "off" we can allow additional segments and text to be added outside that range.

ggplot(data = data.frame(hour = 0:23, value = sin(0:23)),
       aes(hour, value)) +
  geom_line() +
  scale_x_continuous(breaks = 0.5 + 0:23, labels = 0:23, name = "") +
  coord_cartesian(ylim = c(-1,1), xlim = c(0,24), expand = FALSE, clip = "off") +
  geom_segment(data = data.frame(line_x = 6*(0:4)),
               aes(x = line_x, xend = line_x,
                   y = -1, yend = -1.25),
               color = "gray50") +
  geom_text(data = data.frame(text_x = c(3,9,15,21),
                              name = paste("Phase", 1:4)),
            aes(text_x, y = -1.2, label = name),
            size = 3) +
  theme(panel.grid.major.x = element_blank(), 
        axis.ticks.x = element_blank())

enter image description here

Jon Spring
  • 55,165
  • 4
  • 35
  • 53