align y axis labels inward when y axis position is set "right"

Viewed 743

In R {ggplot2} I want to align the most outer axis labels inward, which is no problem for x and y axis labels when the position argument is not specified (see first plot below).

However, when the y axis is positioned right the hjust argument in axis.text.y = element_text() seems not to be responding (see second plot). I know that vectorized input is not officially supported in element_text, but even a vector of length one does not affect the position of the y axis labels.

To be clear: my desired output is similar to the first plot, but with the x axis positioned top and the y axis positioned right. At the moment the word "many" on the y axis is not aligned inwards.

Is this a bug? Do you I need to specify some other arguments?

Any help appreciated.

library(ggplot2)
library(dplyr)

p <- mtcars %>%
  ggplot(aes(x = cyl, y = gear)) +
  geom_point()

# labels are aligned nicely:
p +
  scale_x_continuous(expand = c(0,0),
                     limits = c(4,8),
                     breaks = seq(4, 8, 1),
                     labels = c("few", "", "", "", "many")) +
  scale_y_continuous(expand = c(0,0),
                     limits = c(3, 5),
                     breaks = seq(3, 5, 1),
                     labels = c("few", "", "many")) +
  theme(
    axis.text.x = element_text(
      hjust = c(0, 0, 0, 0, 1)),
    axis.text.y = element_text(
      angle = 90,
      hjust = c(0,0,1)
    )
  )
#> Warning: Vectorized input to `element_text()` is not officially supported.
#> Results may be unexpected or may change in future versions of ggplot2.
#> Warning: Vectorized input to `element_text()` is not officially supported.
#> Results may be unexpected or may change in future versions of ggplot2.

# x labels are aligned nicely
# y labels do not respond to `hjust`
# 'many' should be aligned pointing inwards
p +
  scale_x_continuous(expand = c(0,0),
                     position = "top",
                     trans = "reverse",
                     limits = c(8,4),
                     breaks = seq(8, 4, -1),
                     labels = c("few", "", "", "", "many")) +
  scale_y_continuous(expand = c(0,0),
                     position = "right",
                     trans = "reverse",
                     limits = c(5, 3),
                     breaks = seq(5, 3, -1),
                     labels = c("few", "", "many")) +
  theme(
    axis.text.x = element_text(
      hjust = c(0, 0, 0, 0, 1)),
    axis.text.y = element_text(
      angle = 90,
      hjust = c(0,0,1)
    )
  )
#> Warning: Vectorized input to `element_text()` is not officially supported.
#> Results may be unexpected or may change in future versions of ggplot2.

#> Warning: Vectorized input to `element_text()` is not officially supported.
#> Results may be unexpected or may change in future versions of ggplot2.

Created on 2020-10-26 by the reprex package (v0.3.0)

1 Answers

Not sure whether this is a bug, but I had a similar issue lately. Solution in my case and apparently also in your case is to be more specific and make use of axis.text.y.right:

library(ggplot2)
library(dplyr)

p <- mtcars %>%
  ggplot(aes(x = cyl, y = gear)) +
  geom_point()

p +
  scale_x_continuous(expand = c(0,0),
                     position = "top",
                     trans = "reverse",
                     limits = c(8,4),
                     breaks = seq(8, 4, -1),
                     labels = c("few", "", "", "", "many")) +
  scale_y_continuous(expand = c(0,0),
                     position = "right",
                     trans = "reverse",
                     limits = c(5, 3),
                     breaks = seq(5, 3, -1),
                     labels = c("few", "", "many")) +
  theme(
    axis.text.x = element_text(
      hjust = c(0, 0, 0, 0, 1)),
    axis.text.y.right = element_text(
      angle = 90,
      hjust = c(0,0,1)
    )
  )

Related