Saltar al contenido

Cómo ajustar el tamaño de la faceta manualmente

Después de de una prolongada selección de información hemos podido solucionar esta aprieto que pueden tener ciertos de nuestros lectores. Te brindamos la respuesta y nuestro deseo es resultarte de mucha apoyo.

Solución:

Puede ajustar el ancho de un objeto ggplot usando gráficos de cuadrícula

g = ggplot(df, aes(x,y,color=i)) +
  geom_point() +
  facet_grid(labely~labelx, scales='free_x', space='free_x')

library(grid)
gt = ggplot_gtable(ggplot_build(g))
gt$widths[4] = 4*gt$widths[4]
grid.draw(gt)

ingrese la descripción de la imagen aquí

Con gráficos complejos con muchos elementos, puede resultar un poco engorroso determinar qué ancho desea modificar. En este caso, era la columna 4 de la cuadrícula la que necesitaba expandirse, pero esto variará para diferentes parcelas. Hay varias formas de determinar cuál cambiar, pero una forma bastante sencilla y buena es utilizar gtable_show_layout desde el gtable paquete.

gtable_show_layout(gt)

produce la siguiente imagen:

ingrese la descripción de la imagen aquí

en el que podemos ver que la faceta de la izquierda está en la columna número 4. Las primeras 3 columnas dan espacio para el margen, el título del eje y las etiquetas del eje + ticks. La columna 5 es el espacio entre las facetas, la columna 6 es la faceta de la derecha. Las columnas 7 a 12 son para las etiquetas de la faceta derecha, los espacios, la leyenda y el margen derecho.

Una alternativa a inspeccionar una representación gráfica de gtable es simplemente inspeccionar la propia tabla. De hecho, si necesita automatizar el proceso, esta sería la forma de hacerlo. Así que echemos un vistazo a TableGrob:

gt
# TableGrob (13 x 12) "layout": 25 grobs
#     z         cells       name                                   grob
# 1   0 ( 1-13, 1-12) background        rect[plot.background..rect.399]
# 2   1 ( 7- 7, 4- 4)  panel-1-1               gTree[panel-1.gTree.283]
# 3   1 ( 9- 9, 4- 4)  panel-2-1               gTree[panel-3.gTree.305]
# 4   1 ( 7- 7, 6- 6)  panel-1-2               gTree[panel-2.gTree.294]
# 5   1 ( 9- 9, 6- 6)  panel-2-2               gTree[panel-4.gTree.316]
# 6   3 ( 5- 5, 4- 4)   axis-t-1                         zeroGrob[NULL]
# 7   3 ( 5- 5, 6- 6)   axis-t-2                         zeroGrob[NULL]
# 8   3 (10-10, 4- 4)   axis-b-1    absoluteGrob[GRID.absoluteGrob.329]
# 9   3 (10-10, 6- 6)   axis-b-2    absoluteGrob[GRID.absoluteGrob.336]
# 10  3 ( 7- 7, 3- 3)   axis-l-1    absoluteGrob[GRID.absoluteGrob.343]
# 11  3 ( 9- 9, 3- 3)   axis-l-2    absoluteGrob[GRID.absoluteGrob.350]
# 12  3 ( 7- 7, 8- 8)   axis-r-1                         zeroGrob[NULL]
# 13  3 ( 9- 9, 8- 8)   axis-r-2                         zeroGrob[NULL]
# 14  2 ( 6- 6, 4- 4)  strip-t-1                          gtable[strip]
# 15  2 ( 6- 6, 6- 6)  strip-t-2                          gtable[strip]
# 16  2 ( 7- 7, 7- 7)  strip-r-1                          gtable[strip]
# 17  2 ( 9- 9, 7- 7)  strip-r-2                          gtable[strip]
# 18  4 ( 4- 4, 4- 6)     xlab-t                         zeroGrob[NULL]
# 19  5 (11-11, 4- 6)     xlab-b titleGrob[axis.title.x..titleGrob.319]
# 20  6 ( 7- 9, 2- 2)     ylab-l titleGrob[axis.title.y..titleGrob.322]
# 21  7 ( 7- 9, 9- 9)     ylab-r                         zeroGrob[NULL]
# 22  8 ( 7- 9,11-11)  guide-box                      gtable[guide-box]
# 23  9 ( 3- 3, 4- 6)   subtitle  zeroGrob[plot.subtitle..zeroGrob.396]
# 24 10 ( 2- 2, 4- 6)      title     zeroGrob[plot.title..zeroGrob.395]
# 25 11 (12-12, 4- 6)    caption   zeroGrob[plot.caption..zeroGrob.397]

Los bits relevantes son

#         cells       name  
# ( 7- 7, 4- 4)  panel-1-1      
# ( 9- 9, 4- 4)  panel-2-1              
# ( 6- 6, 4- 4)  strip-t-1

en el que los nombres panel-xy se refieren a paneles en coordenadas x, y, y las celdas dan las coordenadas (como rangos) de ese panel nombrado en la tabla. Entonces, por ejemplo, los paneles superior e inferior izquierdo están ubicados en las celdas de la tabla con los rangos de columna 4- 4. (solo en la columna cuatro, eso es). La franja superior izquierda también está en la columna de celda 4.

Si desea utilizar esta tabla para encontrar el ancho relevante mediante programación, en lugar de manualmente, (utilizando la faceta superior izquierda, es decir "panel-1-1" como ejemplo) podrías usar

gt$layout$l[grep('panel-1-1', gt$layout$name)]
# [1] 4

Ah si muy triste esa funcionalidad para configurar widths y heights en facet_grid se ha ido.

Otra posible solución sin ggplotGrob es establecer el ángulo del texto en theme(strip.text.x=element_text(angle...)) y el ajuste de texto de facetas facet_grid(... labeller=label_wrap_gen(width...)), p.ej

ggplot(df, aes(x,y,color=i)) +
  geom_point() +
  facet_grid(labely~labelx, scales='free_x', space='free_x', labeller=label_wrap_gen(width = 10, multi_line = TRUE)) +
  theme(strip.text.x=element_text(angle=90, hjust=0.5, vjust=0.5))

ingrese la descripción de la imagen aquí

En caso de que esté interesado en modificar ggplot2 en más y otras formas, Recomiendo la viñeta:

vignette("extending-ggplot2")

Ahora, para su problema en cuestión, creo que el atajo de una solución limpia es el siguiente:

library(ggplot2)
DF <- data.frame(labelx = rep(c('my long label','short'), c(2,26)),
                 labely = rep(c('a','b'), each = 14),
                 x = c(letters[1:2], letters[1:26]),
                 y = LETTERS[6:7],
                 i = rnorm(28))

# ad-hoc replacement for the "draw_panels" method, sorry for the hundred lines of code...
# only modification is marked with a comment
draw_panels_new <- function(panels, layout, x_scales, y_scales, ranges, coord, data, theme, params) % theme$panel.spacing)
  panel_table <- gtable_add_row_space(panel_table, theme$panel.spacing.y %

Continuando en un nuevo bloque de código para detener el desplazamiento:

# need to pre-set the same environment to find things like e.g.
# gtable_matrix() from package gtable
environment(draw_panels_new) <- environment(FacetGrid$draw_panels)
# assign custom method
FacetGrid$draw_panels <- draw_panels_new

# happy plotting
ggplot(DF, aes(x, y, color = i)) +
  geom_point() +
  facet_grid(labely~labelx, scales = 'free_x', space = 'free_x')

Digo atajo porque, por supuesto, podrías escribir tu propia versión de facet_grid_new además, te permite pasar los valores c(1,4) desde arriba de forma flexible como extra params.
Y, por supuesto, podrías hacer el tuyo ggproto objeto heredado de FacetGrid...


Editar:

Otra forma sencilla de hacer esto más flexible sería agregar un option, por ejemplo, como:

options(facet_size_manual = list(width = c(1,4), height = NULL))

Esto podría usarse dentro de la costumbre. draw_panels método de alguna manera como este:

if (!is.null(facet_width <- getOption("facet_size_manual")$width))
  widths <- facet_width

No se te olvide dar visibilidad a este enunciado si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *