ggplot: выравнивание нескольких граненых участков-фасеты всех различных размеров
Я пытаюсь выровнять несколько участков с гранями. Моя проблема несколько незначительна, но иррациональна: я могу сделать участок так, чтобы области участка были выровнены, а сами грани выровнены, но полосы граней не все одинаковой ширины. Если метки фасетов имеют разную длину, то полосы фасетов имеют такой размер, чтобы текст мог поместиться внутри фасетов. Я пока не могу найти способ сделать все полосы фасеток одинаковой ширины при выравнивании нескольких участков.
Вот пример: пример типа участков, которые я хочу выровнять, и мои усилия по их выравниванию:
library(data.table)
library(ggplot2)
library(foreach)
library(stringr)
library(cowplot)
# example data to show how aligning faceted plots is not quite right
plotvars = c(paste0("plot1_var", 1:7), paste0("plot2_var",1:5), paste0("plot3_var",1:10))
data =
foreach(p=plotvars,.combine = "rbind") %do% {
d = data.table(plot = rep(str_extract(p,pattern = "plot[[:digit:]]"),2),
plot_variables = rep(p,2),
fill_categories = c("fill1","fill2"),
number = sample(1:1000, size = 2))
d[, facet_variables := ifelse(plot=="plot1",
rep(sample(paste0("facet",1:3),size=1),2),
ifelse(plot=="plot2",
rep(sample(paste0("facet_title",1:3),size=1),2),
ifelse(plot=="plot3",
rep(sample(paste0("facet_title_longer",1:3),size=1),2),
NA)))]
d
}
# function to make stacked barplots with facets + coord_flip
make_plot = function(data, plot_var) {
ggplot(data[plot==plot_var],
aes(x=plot_variables,
y=number,
fill=fill_categories))+
geom_bar(stat="identity")+
coord_flip()+
facet_grid(facet_variables ~ .,
space="free",
scales="free")+
theme(strip.text.y = element_text(angle=0),
legend.position = "none")
}
p1 = make_plot(data=data,plot_var="plot1")
p1
p2 = make_plot(data=data,plot_var="plot2")
p2
p3 = make_plot(data=data,plot_var = "plot3")
p3
# using 'cowplot::plot_grid' gives strange re-sizing of individual bars
cowplot::plot_grid(p1,p2,p3, ncol=1,nrow=3,align = "hv")
# try gtable_rbind version
g1=ggplotGrob(p1)
g2=ggplotGrob(p2)
g3=ggplotGrob(p3)
# this plot keeps the bar widths the correct size, but the facets are still incorrectly different widths.
ggdraw(gridExtra::gtable_rbind(g1,g2,g3))
Как я могу сделать полосы фасеток одинаковой ширины на участках?
3 ответа:
Фасетные полосы завернуты в другую таблицу, и вам нужно отрегулировать ширину там. По-видимому, работает следующее.
g1 <- ggplotGrob(p1) g2 <- ggplotGrob(p2) g3 <- ggplotGrob(p3) # g3 has the widest strips, so get the width from there and copy over # to the other plots stripwidth <- g3$grobs[[13]]$widths g1$grobs[[13]]$widths <- stripwidth g1$grobs[[14]]$widths <- stripwidth g1$grobs[[15]]$widths <- stripwidth g2$grobs[[13]]$widths <- stripwidth g2$grobs[[14]]$widths <- stripwidth g2$grobs[[15]]$widths <- stripwidth ggdraw(gridExtra::gtable_rbind(g1,g2,g3))
Вы можете добиться чего-то подобного с помощью функции labeller, которая вставляет второй ряд пробелов любой длины, которую вы хотите. Используя
mtcars
...#define a function to add a second line of spaces after a given label #and a blank line before to maintain the centre vertical alignment #you might need to play with the appropriate value to get the width right widen <- function(x) paste(" \n", x, "\n", paste0(rep(" ", 20), collapse="")) mtcars %>% ggplot(aes(x = mpg)) + geom_histogram() + facet_grid(cyl ~ ., labeller = labeller(cyl = widen)) + coord_flip() + theme(strip.text.y = element_text(angle = 0))