The "lege artis" way to center justify a plot title in ggplot - plot.title = element_text(hjust = 0.5) - centers the title over plot area excluding axis labels.
This can get ugly when the axis labels are very long, such as this plot of songs in Mary Poppins Soundtrack vs. their character length.
library(tidyverse)
mary_poppins <- data_frame(song = c("Overture", "Sister Suffragette", "The Life I Lead", "The Perfect Nanny", "A Spoonful of Sugar", "Pavement Artist", "Jolly Holiday", "Supercalifragilisticexpialidocious", "Stay Awake", "I Love to Laugh", "A British Bank", "Feed the Birds ", "Fidelity Fiduciary Bank", "Chim Chim Cher-ee", "Step in Time", "A Man Has Dreams", "Let's Go Fly a Kite"
))
mary_poppins <- mary_poppins %>%
mutate(len = nchar(song))
ggplot(data = mary_poppins, aes(x = reorder(song, len), y = len)) +
geom_col(fill = "firebrick") +
coord_flip() +
theme_light() +
theme(axis.title.y = element_blank(),
axis.text = element_text(size = rel(1.5)),
plot.title = element_text(size = rel(2.5), face = "bold", hjust = 0.5,
margin = margin(t = 10, b = 20, unit = "pt"))) +
ggtitle("Mary Poppins") +
ylab("Lenght of title (characters)")
Is there a way to center the title over the total plot area, i.e . including the area taken over by axis labels?
A simple way to solve the problem is to add the following to the plot:
theme(plot.title.position = 'plot',
plot.title = element_text(hjust = 0.5))
The first part tells ggplot
to use the entire plot as a reference for the centering, and the second part centers the title.
As I replied in an essentially duplicate question, you can use the patchwork
library and it's plot_annotation
, so you'll have:
library(tidyverse)
mary_poppins <- data_frame(song = c("Overture", "Sister Suffragette", "The Life I Lead", "The Perfect Nanny", "A Spoonful of Sugar", "Pavement Artist", "Jolly Holiday", "Supercalifragilisticexpialidocious", "Stay Awake", "I Love to Laugh", "A British Bank", "Feed the Birds ", "Fidelity Fiduciary Bank", "Chim Chim Cher-ee", "Step in Time", "A Man Has Dreams", "Let's Go Fly a Kite"
))
mary_poppins <- mary_poppins %>%
mutate(len = nchar(song))
ggplot(data = mary_poppins, aes(x = reorder(song, len), y = len)) +
geom_col(fill = "firebrick") +
coord_flip() +
theme_light() +
theme(axis.title.y = element_blank(),
axis.text = element_text(size = rel(1.5))) +
patchwork::plot_annotation("Mary Poppins",
theme = theme(plot.title = element_text(size = rel(2.5), face = "bold", hjust = 0.5,
margin = margin(t = 10, b = 20, unit = "pt")))) +
ylab("Lenght of title (characters)")
Since plot_annotation
is designed for multipanel plots, it will not inherit the theme of the plot you are constructing, so you need to give it separately. It will however honor any global theme.
The resulting plot is (hopefully) what you need.
Short solution I've found:
theme(plot.title = element_text(hjust = -0.2))
hjust parameter controls distance from the left alignment to the y axis. Negative values move text to the left
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With