Home > database >  Control Discrete Tick Labels in ggplot2 (scale_x_discrete)
Control Discrete Tick Labels in ggplot2 (scale_x_discrete)

Time:12-22

On a continuous scale, I can reduce the density of the tick labels using breaks and get nice control over their density in a flexible fashion using scales::pretty_breaks(). However, I can't figure out how to achieve something similar with a discrete scale. Specifically, if my discrete labels are letters, then let's say that I want to show every other one to clean up the graph. Is there an easy, systematic way to do this?

I have a hack that works (see below) but looking for something more automatic and elegant.

library(tidyverse)

# make some dummy data
dat <-
  matrix(sample(100),
         nrow = 10,
         dimnames = list(letters[1:10], LETTERS[1:10])) %>%
  as.data.frame() %>%
  rownames_to_column("row") %>%
  pivot_longer(-row, names_to = "column", values_to = "value")

# default plot has all labels on discrete axes
dat %>% 
  ggplot(aes(row, column))  
  geom_tile(aes(fill = value))

# desired plot would look like following:
ylabs <- LETTERS[1:10][c(T, NA)] %>% replace_na("")
xlabs <- letters[1:10][c(T, NA)] %>% replace_na("")

# can force desired axis text density but it's an ugly hack
dat %>% 
  ggplot(aes(row, column))  
  geom_tile(aes(fill = value))  
  scale_y_discrete(labels = ylabs)  
  scale_x_discrete(labels = xlabs)

Created on 2021-12-21 by the reprex package (v2.0.1)

CodePudding user response:

One option for dealing with overly-dense axis labels is to use n.dodge:

ggplot(dat, aes(row, column))  
  geom_tile(aes(fill = value))  
  scale_x_discrete(guide = guide_axis(n.dodge = 2))  
  scale_y_discrete(guide = guide_axis(n.dodge = 2))

ggplot with dodging axis labels

Alternatively, if you are looking for a way to reduce your use of xlabs and do it more programmatically, then we can pass a function to scale_x_discrete(breaks=):

everyother <- function(x) x[seq_along(x) %% 2 == 0]
ggplot(dat, aes(row, column))  
  geom_tile(aes(fill = value))  
  scale_x_discrete(breaks = everyother)  
  scale_y_discrete(breaks = everyother)

ggplot with alternating label removal

  • Related