Skip to content

Instantly share code, notes, and snippets.

@padpadpadpad
Last active February 11, 2019 16:40
Show Gist options
  • Select an option

  • Save padpadpadpad/1317468e6cb9ec4ad68847fef4b72f7c to your computer and use it in GitHub Desktop.

Select an option

Save padpadpadpad/1317468e6cb9ec4ad68847fef4b72f7c to your computer and use it in GitHub Desktop.
makes a multi-row x axis on ggplot2.
# load packages
library(ggplot2)
library(dplyr)
library(tidyr)
# create dummy data
df=data.frame(PM=as.factor(1:8),
phase=rep(c('1', '2'),each = 4),
y=rnorm(8, mean = 10, sd = 3))
# create new label for second x axis
df$new_label <- ifelse(df$phase == '1', 'Year: 2015', 'Year: 2016')
# create spacing for second axis
# took a little bit of time because I wanted it to be reproducible if you had three years etc. -_-
spacing <- group_by(df, new_label, phase) %>%
summarise(., num = n()) %>%
mutate(x = lag(cumsum(num), n = 1, default = 0),
x = x + num/2 + 0.5)
# make plot
g1 <- ggplot(data = df, aes(x = interaction(phase, PM, lex.order = TRUE),
y = y, group = 1)) +
geom_point() +
# here your limits need to be stated - change the coord_cartesian line
# xlim(c(0, 30)) - max is number of pine martens + 1
coord_cartesian(ylim = c(0, 20), xlim = c(0, 9), expand = FALSE) +
annotate(geom = "text", x = seq_len(nrow(df)), y = -1, label = df$PM, size = 4) +
annotate(geom = "text", x = spacing$x, y = -2, label = unique(df$phase), size = 6) +
theme_bw() +
theme(plot.margin = unit(c(2, 2, 4, 2), "lines"),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())
# remove clipping of x axis labels
g2 <- ggplot_gtable(ggplot_build(g1))
g2$layout$clip[g2$layout$name == "panel"] <- "off"
grid::grid.draw(g2)
# alternative can move the facet to the bottom ####
# load packages
library(ggplot2)
library(dplyr)
library(tidyr)
# create dummy data
df=data.frame(PM=as.factor(1:8),
phase=rep(c('1', '2'),each = 4),
y=rnorm(8, mean = 10, sd = 3))
# create new label for second x axis
df$new_label <- ifelse(df$phase == '1', 'Year: 2015', 'Year: 2016')
# create spacing for second axis
# took a little bit of time because I wanted it to be reproducible if you had three years etc. -_-
spacing <- group_by(df, new_label, phase) %>%
summarise(., num = n()) %>%
mutate(x = lag(cumsum(num), n = 1, default = 0),
x = x + num/2 + 0.5)
# make plot
g1 <- ggplot(data = df, aes(x = interaction(phase, PM, lex.order = TRUE),
y = y, group = 1)) +
geom_point() +
# here your limits need to be stated - change the coord_cartesian line
# xlim(c(0, 30)) - max is number of pine martens + 1
coord_cartesian(ylim = c(0, 20), xlim = c(0, 9), expand = FALSE) +
annotate(geom = "text", x = seq_len(nrow(df)), y = -1, label = df$PM, size = 4) +
annotate(geom = "text", x = spacing$x, y = -2, label = unique(df$phase), size = 6) +
theme_bw() +
theme(plot.margin = unit(c(2, 2, 4, 2), "lines"),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())
# remove clipping of x axis labels
g2 <- ggplot_gtable(ggplot_build(g1))
g2$layout$clip[g2$layout$name == "panel"] <- "off"
grid::grid.draw(g2)
# alternative
# create dataframe to label plots
label <- data.frame(new_label = unique(df$new_label), text = c('(a)', '(b)'))
ggplot(data = df, aes(x = PM,
y = y, group = 1)) +
geom_point() +
theme_bw() +
theme(panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
strip.placement = 'outside',
strip.background = element_blank(),
strip.text.x = element_text(size = 14)) +
geom_text(aes(-Inf, Inf, label = text), label, vjust = 2, hjust = -0.8) +
facet_wrap(~new_label, strip.position = 'bottom')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment