a_todd12
a_todd12

Reputation: 550

How to add white space and extra axis labels to ggplot figure

I am trying to make a geom_point figure with each 'var' group along the x axis.

As you can see in my data, the 'vars' fall into 3 broader groupings: Strength, Race/Ethnicity, and City.

So what I am trying to do is add a little white space in the figure between each of those groupings, and also add an additional x axis label for each of them (besides Total). For example, centered beneath the race/ethnicity categories would be an additional label that says "Race" or something along those lines. Is there a way to do this? Thanks.

Code here

order1 <- c("Total", "Weak", "Strong", "White", "Black", "Hispanic", "Springfield", "Buxton", "Artowne", "Friedsville", "Alexandria", "Oldmill")

data %>% 
  ggplot(., aes(y = mean, x = var, color = var)) +
  geom_point() +
  geom_pointrange(aes(ymin = lower, ymax = upper)) +
  scale_x_discrete(limits = order1) +
  labs(x = NULL) +
  theme_classic() +
  theme(legend.position = "none")

Example data here

structure(list(category = c("points", "points", "points", "points", 
"points", "points", "points", "points", "points", "points", "points", 
"points"), var = c("Total", "Weak", "Strong", "White", "Black", 
"Hispanic", "Springfield", "Buxton", "Artowne", "Friedsville", 
"Alexandria", "Oldmill"), mean = c(175, 145, 160, 120, 200, 200, 
225, 200, 100, 160, 120, 100), lower = c(156, 120, 140, 100, 
168, 141, 191, 72, 45, 130, 100, 40), upper = c(190, 176, 185, 
150, 245, 240, 280, 340, 230, 200, 150, 150)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -12L))

Upvotes: 0

Views: 158

Answers (1)

stefan
stefan

Reputation: 123783

One option would be to use faceting, i.e. add a column with the categories, then facet by that column. As the categories have different number of items I opted for facet_grid with space = "free_x" and scales = "free_x", placed the strip labels at the bottom and used theme options to place the stripe text on the outside of the axis and to get rid of the outline.

library(ggplot2)
library(dplyr, warn = FALSE)

data |>
  mutate(
    var = factor(var, order1),
    category = case_match(
      var,
      c("Weak", "Strong") ~ "Strength",
      c("White", "Black", "Hispanic") ~ "Race",
      c(
        "Springfield", "Buxton", "Artowne",
        "Friedsville", "Alexandria", "Oldmill"
      ) ~ "City",
      .default = ""
    ),
    category = factor(category, c("", "Strength", "Race", "City"))
  ) |>
  ggplot(aes(y = mean, x = var, color = var)) +
  geom_point() +
  geom_pointrange(aes(ymin = lower, ymax = upper)) +
  facet_grid(. ~ category,
    space = "free_x", scales = "free_x",
    switch = "x"
  ) +
  labs(x = NULL) +
  theme_classic() +
  theme(
    legend.position = "none",
    strip.placement = "outside",
    strip.background.x = element_rect(color = NA)
  )

UPDATE You could use a labelling function using e.g. dplyr::case_mtach to assign different labels to the x axis categories which can be passed to the labels= argument of scale_x_discrete like so:

labels_x <- function(x) {
  case_match(
    x,
    "Friedsville" ~  "Frieds\nVille",
    "Springfield" ~  "Spring-\nfield",
    .default = x
  )
}

data |>
  mutate(
    var = factor(var, order1),
    category = case_match(
      var,
      c("Weak", "Strong") ~ "Strength",
      c("White", "Black", "Hispanic") ~ "Race",
      c(
        "Springfield", "Buxton", "Artowne",
        "Friedsville", "Alexandria", "Oldmill"
      ) ~ "City",
      .default = ""
    ),
    category = factor(category, c("", "Strength", "Race", "City"))
  ) |>
  ggplot(aes(y = mean, x = var, color = var)) +
  geom_point() +
  geom_pointrange(aes(ymin = lower, ymax = upper)) +
  scale_x_discrete(labels = labels_x) +
  facet_grid(. ~ category,
    space = "free_x", scales = "free_x",
    switch = "x"
  ) +
  labs(x = NULL) +
  theme_classic() +
  theme(
    legend.position = "none",
    strip.placement = "outside",
    strip.background.x = element_rect(color = NA)
  )

Upvotes: 1

Related Questions