I want to write the y-axis title horizontally on top of the y-axis line while keeping settings defined for the y-axis in the theme()
function. The objective is to avoid wasting space while keeping a nice looking design (e.g. with the title left-aligned with y-axis-ticks-labels).
I know it is possible to use other "hacks" (see
It is possible to start with theme(axis.title.y = element_text(angle = 0, vjust = 1))
but the y-axis title is not on top of the line.
This code removes the y-axis title while keeping the theme()
parameters defined for the grob:
library(ggplot2)
library(grid)
p <- ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length))
theme(axis.title.y = element_text(angle = 0, vjust = 1),
axis.title.x = element_blank())
# convert from ggplot to grob object
gp <- ggplotGrob(p)
# locate the grob that corresponds to y-axis title and save its parameters
y.label.grob <- gp$grobs[[which(gp$layout$name == "ylab-l")]]$children
# remove y-axis labels from the plot, & shrink the space occupied by them
gp$grobs[[which(gp$layout$name == "ylab-l")]] <- zeroGrob()
gp$widths[gp$layout$l[which(gp$layout$name == "ylab-l")]] <- unit(0, "cm")
But now I am stuck as I do not know how to use functions from the grid
package to move the title where I would like to (i.e. on the top left corner).
CodePudding user response:
You can exceed vjust
beyond 1 and adapt the margins a bit. It's hard to get the alignment perfectly though.
library(ggplot2)
library(grid)
ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length))
theme(
plot.margin = margin(t = 30),
axis.title.y = element_text(
angle = 0, vjust = 1.1,
margin = margin(r = -50, t = 5.5, b = 5.5, l = 5.5)),
axis.title.x = element_blank()
)
If you know the title in advance you can use it's string width.
ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length))
theme(
plot.margin = margin(t = 30),
axis.title.y = element_text(
angle = 0, vjust = 1.07,
margin = unit.c(
unit(c(2.75), "pt"),
unit(-1, "strwidth", data = "Petal.Length"),
unit(c(2.75, 2.75), "pt")
)
),
axis.title.x = element_blank()
)