Questa domanda è motivata esplorando ulteriormente questo question. Il problema con la soluzione accettata diventa più evidente quando c'è una maggiore disparità nel numero di barre per faccetta. Date un'occhiata a questi dati e la trama risultante utilizzando tale soluzione:ggplot2 + gridExtra: come garantire che geom_bar in trame di dimensioni diverse corrisponda esattamente alla stessa larghezza della barra
# create slightly contrived data to better highlight width problems
data <- data.frame(ID=factor(c(rep(1,9), rep(2,6), rep(3,6), rep(4,3), rep(5,3))),
TYPE=factor(rep(1:3,length(ID)/3)),
TIME=factor(c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,1,1,1)),
VAL=runif(27))
# implement previously suggested solution
base.width <- 0.9
data$w <- base.width
# facet two has 3 bars compared to facet one's 5 bars
data$w[data$TIME==2] <- base.width * 3/5
# facet 3 has 1 bar compared to facet one's 5 bars
data$w[data$TIME==3] <- base.width * 1/5
ggplot(data, aes(x=ID, y=VAL, fill=TYPE)) +
facet_wrap(~TIME, ncol=1, scale="free") +
geom_bar(position="stack", aes(width = w),stat = "identity") +
coord_flip()
noterete le larghezze apparire esattamente a destra, ma gli spazi in sfaccettatura 3 è abbastanza lampante. Non c'è un modo semplice per risolvere questo problema in ggplot2 che ho già visto (facet_wrap non ha un'opzione space
).
passo successivo è quello di cercare di risolvere questo utilizzando gridExtra:
# create each of the three plots, don't worry about legend for now
p1 <- ggplot(data[data$TIME==1,], aes(x=ID, y=VAL, fill=TYPE)) +
facet_wrap(~ TIME, ncol=1) +
geom_bar(position="stack", show_guide=FALSE) +
coord_flip()
p2 <- ggplot(data[data$TIME==2,], aes(x=ID, y=VAL, fill=TYPE)) +
facet_wrap(~ TIME, ncol=1) +
geom_bar(position="stack", show_guide=FALSE) +
coord_flip()
p3 <- ggplot(data[data$TIME==3,], aes(x=ID, y=VAL, fill=TYPE)) +
facet_wrap(~ TIME, ncol=1) +
geom_bar(position="stack", show_guide=FALSE) +
coord_flip()
# use similar arithmetic to try and get layout correct
require(gridExtra)
heights <- c(5, 3, 1)/sum(5, 3, 1)
print(arrangeGrob(p1 ,p2, p3, ncol=1,
heights=heights))
si noterà che ho usato lo stesso aritmetica già suggerito in base al largo il numero di barre per sfaccettatura, ma in questo caso finisce male orribilmente. Questo sembra essere dovuto al fatto che ci sono elementi extra "di altezza costante" che devo prendere in considerazione in matematica.
Un'altra complicazione (credo) è che l'output finale (e se le larghezze corrispondano o meno) dipenderà anche dalla larghezza e dall'altezza di dove sto emettendo il grob finale, sia esso in un R/RStudio ambiente, o in un file PNG.
Come posso realizzare questo?
con 'ggplot_build' è possibile modificare direttamente l'altezza di ogni pannello nella vostra prima soluzione. kohske ha pubblicato esempi qui – baptiste
@baptiste grazie, daremo un'occhiata e aggiorneremo presto la domanda –