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))
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)