How do I set the legend height or width to be 100% of the plot height/width regardless of the actual dimensions?
library(ggplot2)
ggplot(iris, aes(Petal.Width, Sepal.Width, color=Petal.Length))+
geom_point()+
theme(
legend.title=element_blank(),
legend.position="bottom",
legend.key.width=unit(0.1,"npc"))

Created on 2022-02-11 by the reprex package (v2.0.1)
Session infosessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#> setting value
#> version R version 4.1.0 (2021-05-18)
#> os Ubuntu 20.04.3 LTS
#> ─ Packages ───────────────────────────────────────────────────────────────────
#> ggplot2 * 3.3.5 2021-06-25 [1] CRAN (R 4.1.0)
#>
#> ──────────────────────────────────────────────────────────────────────────────
Please forgive me for double answers, but I believe this to be a totally different approach, and the credits for the idea go to @benson23.
We can use ggh4x::force_panelsizes() to set an absolute size for the panel and match the width of the bar. Upside is that it is reasonably easy to do, downside is that your plot's width doesn't automagically adapts to the window size anymore.
library(ggplot2)
library(ggh4x)
width <- unit(10, "cm")
ggplot(iris, aes(Petal.Width, Sepal.Width, color=Petal.Length))+
geom_point() +
guides(colour = guide_colorbar(barwidth = width)) +
force_panelsizes(cols = width) +
theme(
legend.title=element_blank(),
legend.position="bottom",
legend.spacing.x = unit(0, "cm"))

The process becomes slightly more complicated if a plot has multiple panels, but it is not undoable.
ncol <- 3
total_width <- unit(10, "cm")
# Optionally: replace `theme_get()` with actual theme you're using
spacing <- calc_element("panel.spacing.x", theme_get())
panel_widths <- (total_width - spacing * (ncol - 1)) / ncol
ggplot(iris, aes(Petal.Width, Sepal.Width, color=Petal.Length))+
geom_point() +
guides(colour = guide_colorbar(barwidth = total_width)) +
facet_wrap(~ Species, ncol = ncol) +
force_panelsizes(cols = panel_widths) +
theme(
legend.title=element_blank(),
legend.position="bottom",
legend.spacing.x = unit(0, "cm"))

Created on 2022-02-11 by the reprex package (v2.0.1)
Disclaimer: I'm the author of {ggh4x}
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