Placing the legend above the main title in ggplot2
when using theme(legend.position = "top")
seemed to be the default (and unwanted) outcome in previous versions of ggplot: ggplot legend at top but below title?
In the current version of ggplot2
, the legend places itself between the plot and the main title when setting theme(legend.position = "top")
. A small example:
d <- data.frame(x = 1:2, y = 1:2, z = c("a", "b"))
ggplot(d, aes(x = x, y = y, fill = z)) +
geom_col() +
ggtitle("My title") +
theme(legend.position = "top")
How can I place the legend above main title?
library(ggplot2)
ggplot(mtcars, aes(wt, mpg, color=cyl)) +
geom_point() +
labs(title = "Hey") +
theme(plot.margin = margin(t=4,1,1,1, "lines")) +
theme(legend.direction = "horizontal") +
theme(legend.position = c(0.5, 1.2))
There are other ways as well, but this was the easiest one that came to mind.
This requires a little more work than adjusting margins, but it should allow for more control over placement and sizing. I'm using functions from cowplot
: get_legend
to extract the legend from the plot, and plot_grid
to create a grid of these two ggplot
elements.
After creating the plot p
with a legend, cowplot::get_legend(p)
then creates a ggplot
object that is just the legend. Reposition them with plot_grid
while adding a theme
call that removes the legend from p
. You'll probably want to tweak the heights and perhaps adjust margins.
library(ggplot2)
p <- ggplot(d, aes(x = x, y = y, fill = z)) +
geom_col() +
ggtitle("My title") +
theme(legend.position = "bottom")
legend <- cowplot::get_legend(p)
cowplot::plot_grid(
legend,
p + theme(legend.position = "none"),
ncol = 1, rel_heights = c(0.1, 1)
)
Created on 2018-10-12 by the reprex package (v0.2.1)
Or we can create a fake facet and put the plot title in it. After that do some tweaking to remove the strip facet and reduce the legend margin
library(ggplot2)
d <- data.frame(x = 1:2, y = 1:2, z = c("a", "b"))
d$Title <- "My title\n"
# default legend key text
p1 <- ggplot(d, aes(x = x, y = y, fill = z)) +
geom_col() +
facet_grid(~ Title) +
theme(strip.text.x = element_text(hjust = 0, vjust = 1,
size = 14, face = 'bold'),
strip.background = element_blank()) +
theme(legend.margin = margin(5, 0, 0, 0),
legend.box.margin = margin(0, 0, -10, 0)) +
theme(legend.position = "top") +
NULL
# legend key text at the bottom
p2 <- ggplot(d, aes(x = x, y = y, fill = z)) +
geom_col() +
facet_grid(~ Title) +
theme(strip.text.x = element_text(hjust = 0, vjust = 1,
size = 14, face = 'bold'),
strip.background = element_blank()) +
theme(legend.margin = margin(5, 0, 0, 0),
legend.box.margin = margin(0, 0, -10, 0)) +
guides(fill = guide_legend(label.position = "bottom",
title.position = "left", title.vjust = 1)) +
theme(legend.position = "top") +
NULL
library(patchwork)
p1 | p2
Created on 2018-10-12 by the reprex package (v0.2.1.9000)