How can I adjust the legend colorbar height to match the height of my plots when using facet_wrap()
? This related SO question offers a good solution for a single plot, but when multiple plots are present, the color bar extends halfway through the facet wrap title and axis text. I would like the colorbar to extend only from the base of the facet wrap title to the top of the axis text.
library(tidyverse)
library(ggcorrplot)
library(reshape2)
iris %>%
group_by(Species) %>%
summarise(correlation = list(cor(across(where(is.numeric))))) %>%
ungroup() %>%
mutate(correlation_df = map(correlation, ~ melt(.x, varnames = c("Var1", "Var2")))) %>%
select(Species, correlation_df) %>%
unnest(correlation_df) %>%
ggplot(aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(limit = c(-1, 1)) +
labs(x = NULL,
y = NULL,
fill = NULL) +
theme_bw() +
facet_wrap(~Species)
make_fullsize <- function() structure("", class = "fullsizebar")
ggplot_add.fullsizebar <- function(obj, g, name = "fullsizebar") {
h <- ggplotGrob(g)$heights
panel <- which(grid::unitType(h) == "null")
panel_height <- unit(1, "npc") - sum(h[-panel])
g +
guides(fill = guide_colorbar(barheight = panel_height,
title.position = "right")) +
theme(legend.title = element_text(angle = -90, hjust = 0.5))
}
iris %>%
group_by(Species) %>%
summarise(correlation = list(cor(across(where(is.numeric))))) %>%
ungroup() %>%
mutate(correlation_df = map(correlation, ~ melt(.x, varnames = c("Var1", "Var2")))) %>%
select(Species, correlation_df) %>%
unnest(correlation_df) %>%
ggplot(aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(limit = c(-1, 1)) +
labs(x = NULL,
y = NULL,
fill = NULL) +
theme_bw() +
coord_cartesian(expand = FALSE) +
make_fullsize() +
facet_wrap(~Species)
Created on 2024-12-30 with reprex v2.1.1
panel_height
for example, panel_height <- unit(0.95...
which provides a close yet imprecise answer. This answer also doesn't scale well when making the plots larger/smaller.Edited based on Allan Cameron's comment:
library(tidyverse)
library(ggcorrplot)
library(reshape2)
iris %>%
group_by(Species) %>%
summarise(correlation = list(cor(across(where(is.numeric))))) %>%
ungroup() %>%
mutate(correlation_df = map(correlation, ~ melt(.x, varnames = c("Var1", "Var2")))) %>%
select(Species, correlation_df) %>%
unnest(correlation_df) %>%
ggplot(aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(limit = c(-1, 1)) +
labs(x = NULL,
y = NULL,
fill = NULL) +
theme_bw() +
facet_wrap(~Species) +
theme(legend.key.height = unit(1, "null"),
legend.margin = margin(0, 0, 0, 0))
By assigning the unit to null within the legend.key.height
parameter, the guide not only vertically fits to the plot, but also stretches if you change the aspect ratio of the plot. According to this tidyverse.org article, this feature is still experimental.
(Edit based on Allan Cameron's comment) You can then add legend.margin = margin(0, 0, 0, 0)
within the theme so the legend is vertically aligned with the top and bottom of the plot.