Dunois
Dunois

Reputation: 1843

ggplot2: how to horizontal center legend at top of plot with long Y-axis labels?

I am attempting to plot some data with really long Y-axis labels. I want to position the legend at the top of the plot, and center it horizontally w.r.t. the entire plot width (as dictated by the width of the panel + the Y-axis labels). I can't seem to figure out how to do this.

Here is the toy data I have been working with:

library(magrittr)
library(dplyr)
library(ggplot2)

iris_new <- iris

iris_new %<>% 
  mutate(Sepal.Width = paste0(Sepal.Width, 
                              paste0(sample(letters, size = 100, replace = TRUE), 
                                     collapse = "")))

plt0 <- ggplot(iris_new, aes(Sepal.Length, Sepal.Width, color = Species)) + 
  geom_point() + theme(legend.position = "top", legend.direction = "horizontal")

plt0

The basic plot: plt0

legend.justification = "left" simulates what I want, but not perfectly since it is simply aligning the legend to the left margin of the panel, and it just so happens that this approximately coincides with the middle of the plot width.

plt1 <- plt0 + theme(legend.justification = "left")
plt1

plt1

But this solution isn't really satisfactory as I cannot guarantee that the Y-axis labels might not get longer (or shorter). Of course, I could use stringr::str_wrap() to limit the label width to say 40 characters, but I really want to know if there is a simple ggplot2 solution to the alignment issue. This would also not account for the fact that the plotted data might force the X-axis to vary between plots.

guides(fill = guide_legend(title.position = "left", label.position = "left")) and guides(fill = guide_legend(title.hjust = 0, label.hjust = 0)) didn't work either.

The expected output would be something like this (simulated using LibreOffice Impress): plt2

I apologize if this is a trivial question. I did try and search for relevant posts on stackoverflow, but I was unable to find a solution.

Upvotes: 0

Views: 668

Answers (1)

PesKchan
PesKchan

Reputation: 978

This is close to what you require

p1 <-ggplot(iris_new, aes(Sepal.Length, Sepal.Width, color = Species)) + 
  geom_point()

p2 <- p1 + theme(legend.position = "top")
le1 <- cowplot::get_legend(p1)
le1


cowplot::plot_grid(p2, le1, nrow = 2, rel_heights = c(1, 0.2))

Although I do see another legend at the bottom not sure how to remove it but horizontal center its close

fig

Upvotes: 0

Related Questions