Christian
Christian

Reputation: 1052

Perfectly aligning axis titles to axis edges

For ggplot2 plots, hjust and vjust are alignment functions defined relatively to the entire plot. So when they are applied to axis labels, they are not defined relatively to the axis lines.

However, it is more natural to adjust the axis titles relatively to the axis lines.

Specifically, I'm looking for a way to left-align the x axis title and to top-align and rotate the y axis title.

How can one do this?

Aligned axis titles

Upvotes: 2

Views: 1052

Answers (1)

Christian
Christian

Reputation: 1052

As specified in the question, hjust and vjust are alignment functions defined relatively to the entire plot.

Hence, hjust=0 will not achieve a perfect left-alignment relatively to beginning of the x axis line. However, it can work in combination with expand_limits and scale_x_continuous.

And similarly with scale_y_continuous for the y axis title.

In the question's attached image, the plot begins in the origin. So first, we must force the plot to actually start in the origin:

... +
  expand_limits(x = 0, y = 0) +
  scale_x_continuous(expand = c(0, 0)) + 
  scale_y_continuous(expand = c(0, 0))

We can then specify the adjustments—here also added with the rotation for the y axis title, which then requires that we use hjust instead of vjust:

... +
theme(
  axis.title.x = element_text(hjust = 0),
  axis.title.x = element_text(angle = 90, hjust = 1)
)

Full working example

First, we load ggplot2 and create a data set:

library(ggplot2) 

df <- data.frame(
  x = c(0, 50, 100),
  y = c(20, 40, 80)
)

We create the plot and add a geom_line().

graph <- 
  ggplot(data=df, mapping = aes(x=x, y=y)) +
  geom_line()

We fix our axes. As an added bonus for better control of the axes, I also define the axes ranges (limits).

graph <-
  graph +
  scale_x_continuous(expand = c(0,0), limits = c(min(df$x), max(df$x))) +
  scale_y_continuous(expand = c(0,0), limits = c(min(df$y), max(df$y)))

Then, we format the axis titles. For better visual representation, I've also added a margin to move the titles slightly away from the axis lines.

graph <-
  graph +
  theme(
    axis.title.x = element_text(hjust = 0, margin = margin(t=6)),
    axis.title.y = element_text(angle = 90, hjust = 1, margin=margin(r=6))
  )

And finally, we add the axis titles:

graph <-
  graph +
  xlab("This is the x axis") + 
  ylab("This is the y axis")

The result:

enter image description here

However, this cuts off the last label text (with the last 0 in 100 being only partially visible). To handle this, we must increase the plot margin, here exemplified with a 1 cm margin around all sides:

graph <-
  graph +
  theme(plot.margin = margin(1, 1, 1, 1, "cm"))

The final result:

enter image description here

The full code

library(ggplot2)


df <- data.frame(
  x = c(0, 50, 100),
  y = c(20, 40, 80)
)

graph <-
  ggplot(data=df, mapping = aes(x=x, y=y)) +
  geom_line() +
  expand_limits(x = 0, y = 0) +
  scale_x_continuous(expand = c(0,0), limits = c(min(df$x), max(df$x))) +
  scale_y_continuous(expand = c(0,0), limits = c(min(df$y), max(df$y))) +
  theme(
    axis.title.x = element_text(hjust = 0, margin = margin(t=6)),
    axis.title.y = element_text(angle = 90, hjust = 1, margin=margin(r=6)),
    plot.margin = margin(1, 1, 1, 1, "cm")
  ) +
  xlab("This is the x axis") + 
  ylab("This is the y axis")
    
  

Upvotes: 5

Related Questions