Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`ggplot2` axis.text margin with modified scale position

Tags:

r

ggplot2

I'm not sure if I've encountered a bug or am doing incorrectly. When specifying axis.text margins in ggplot, and moving the position of the axis, the settings to not persist.

Without moving the axis text, there is plenty of space around the axis:

library(ggplot)

ggplot(mtcars, aes(mpg, wt)) +
    geom_point() +
    theme(axis.text.y = element_text(color = "red", margin = margin(40, 40, 40, 40)))

plot with extra margins

But, when the position is changed, the margins do not apply:

ggplot(mtcars, aes(mpg, wt)) +
    geom_point() +
    scale_y_continuous(position = "right") + #This is the new line
    theme(axis.text.y = element_text(color = "red", margin = margin(40, 40, 40, 40))) 

enter image description here

I'd expect the margins to carry over regardless of whether the axis.text is on the right or left. Am I doing something wrong?

like image 707
Andrew Jackson Avatar asked Nov 05 '18 18:11

Andrew Jackson


1 Answers

I believe this arises because the appearance of the right side y-axis label is dictated by axis.text.y.right in theme(), and while it inherits from axis.text.y, it only inherits arguments that are not stated in axis.text.y.right itself.

According to details in ?theme, the chain of inheritance for axis.text.y.right goes as follows:

axis.text.y.right -> axis.text.y -> axis.text -> text

The default theme in ggplot is theme_grey. Enter theme_grey (without () at the end) into your console, and you'll see the full function. Let's look at the relevant bits:

function(base_size = 11, base_family = "", base_line_size = base_size/22, 
         base_rect_size = base_size/22) {

  half_line <- base_size/2

  theme(text = element_text(family = base_family, 
                            face = "plain", 
                            colour = "black",
                            size = base_size, 
                            lineheight = 0.9, 
                            hjust = 0.5, 
                            vjust = 0.5, 
                            angle = 0, 
                            margin = margin(), 
                            debug = FALSE), 

        axis.text = element_text(size = rel(0.8), 
                                 colour = "grey30"), 

        axis.text.y = element_text(margin = margin(r = 0.8 * half_line/2), 
                                   hjust = 1), 

        axis.text.y.right = element_text(margin = margin(l = 0.8 * half_line/2), 
                                         hjust = 0), 
        ...
        complete = TRUE)
}

?element_text shows the full list of arguments that element_text expects:

element_text(family = NULL, face = NULL, colour = NULL, size = NULL,
  hjust = NULL, vjust = NULL, angle = NULL, lineheight = NULL,
  color = NULL, margin = NULL, debug = NULL, inherit.blank = FALSE)

Given all the inheritance, what are axis.text.y.right's actual arguments in theme_grey?

  • family = base_family (from text)
  • face = "plain" (from text)
  • colour = "grey30" (from axis.text, which overrides text's "black")
  • size = 80% of base_size (from axis.text's rel(0.8) modification of text's base_size)
  • hjust = 0 (from axis.text.y.right, which overrides axis.text.y's 1, which overrides text's 0.5)
  • vjust = 0.5 (from text)
  • angle = 0 (from text)
  • lineheight = 0.9 (from text)
  • margin = margin(l = 0.8 * half_line/2) (from axis.text.y.right, which overrides axis.text.y's margin = margin(r = 0.8 * half_line/2, which overrides text's margin())
  • debug = FALSE (from text)
  • inherit.blank = FALSE (element_text's default parameter)

As such, given a piece of code like below, axis.text.y.right will inherit color = "red" (which overrides axis.text's colour = "grey30"). But since it has its own margin argument, it will not inherit margin = margin(40, 40, 40, 40):

ggplot(mtcars, aes(mpg, wt)) +
    geom_point() +
    scale_y_continuous(position = "right") +
    theme(axis.text.y = element_text(color = "red", margin = margin(40, 40, 40, 40))) 

Specifying axis.text.y.right instead of axis.text.y would do the trick:

ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  scale_y_continuous(position = "right") +
  theme(axis.text.y.right = element_text(color = "red", margin = margin(40, 40, 40, 40))) 
like image 184
Z.Lin Avatar answered Oct 25 '22 17:10

Z.Lin