8  A list of quad_layout()

Similarly, stack_layout() can be added to a quad_layout(), and a quad_layout() can also be added to a stack_layout().

Code
library(ggalign)
#> Loading required package: ggplot2
set.seed(123)
small_mat <- matrix(rnorm(56), nrow = 7)
rownames(small_mat) <- paste0("row", seq_len(nrow(small_mat)))
colnames(small_mat) <- paste0("column", seq_len(ncol(small_mat)))

note: when stack_layout() contains a nested quad_layout(), it cannot be used within the annotation of another quad_layout().

8.1 Add quad_layout() to stack_layout()

Here is a summarized table showing which quad_layout() can be used with each stack_layout():

stack_discreteh() stack_discretev() stack_continuoush() stack_continuousv()
quad_continuous()/ggside()
quad_layout(xlim = ...)
quad_layout(ylim = ...)
quad_discrete()/ggheatmap()

As long as the alignment is consistent across both stack_layout() and quad_layout(), you can directly add quad_layout().

stack_discreteh(small_mat) +
    ggheatmap()
#> → heatmap built with `geom_tile()`

When ggheatmap()/quad_layout() is added to a stack_layout(), it will also set the active context to itself, which means subsequent addition will be directed to ggheatmap()/quad_layout(). One exception is the ggheatmap()/quad_layout() itself, which cannot be added to another quad_layout(). In this case, they will be added directly to the stack_layout().

stack_discretev(small_mat) +
    ggheatmap() +
    ggheatmap() +
    scale_fill_viridis_c()
#> → heatmap built with `geom_tile()`
#> → heatmap built with `geom_tile()`

The data of ggheatmap()/quad_layout() can inherit from the stack_layout(), but the data format must match. Otherwise, you will need to manually provide the data.

quad_continuousv_plot <- quad_layout(small_mat, xlim = NULL) +
    geom_boxplot(aes(value, .discrete_y, fill = .row_names)) +
    scale_fill_brewer(palette = "Dark2")
# `stack_continuous()` need a data frame
stack_continuousv() +
    quad_continuousv_plot +
    quad_continuousv_plot

When ggheatmap()/quad_layout() is added to a vertical stack_layout(), the inherited matrix is transposed before use. This is because the columns of ggheatmap()/quad_layout() must match the number of observations in stack_layout().

stack_discretev(small_mat) +
    ggheatmap() +
    ggheatmap()
#> → heatmap built with `geom_tile()`
#> → heatmap built with `geom_tile()`

stack_discrete() ensures that all plots aligned along the stack have the same ordering index or groups.

We can customize the layout in the stack_discrete() directly, or in quad_layout(). As introduced in Section 2.5, you can easily switch from the ggheatmap()/quad_layout() to the stack_layout() using stack_active().

stack_discretev(small_mat) +
    ggheatmap() +
    ggheatmap() +
    anno_bottom(size = 0.2) +
    align_dendro(aes(color = branch), k = 3)+
    layout_title("dendrogram in ggheatmap()")
#> → heatmap built with `geom_tile()`
#> → heatmap built with `geom_tile()`

stack_discretev(small_mat) +
    ggheatmap() +
    ggheatmap() +
    stack_active() +
    align_dendro(aes(color = branch), k = 3, size = 0.2) +
    scale_y_reverse() +
    layout_title("dendrogram in stack_layout()")
#> → heatmap built with `geom_tile()`
#> → heatmap built with `geom_tile()`

When applied to a stack_layout(), the orientation of the dendrogram may need to be manually adjusted.

8.2 Control sizes

A numeric or a unit object of length 3 should be provided in stack_discrete()/stack_continuous() when placing a quad_layout(). For vertical stack_layout(), this means quad_layout() with left or right annotations; for horizontal stack_layout(), this means quad_layout() with top or bottom annotations. The first size controls the relative width/height of the left or top annotation, the second controls the relative width/height of the main plot, and the third controls the relative width/height of the right or bottom annotation.

By default the three rows/columns will have equal sizes.

stack_discretev(small_mat) +
    ggheatmap() +
    theme(axis.text.x = element_text(angle = -60, hjust = 0)) +
    anno_left() +
    align_dendro(aes(color = .panel), k = 3L) +
    anno_right() +
    ggalign(data = rowSums) +
    geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity") +
    ggheatmap() +
    theme(axis.text.x = element_text(angle = -60, hjust = 0))
#> → heatmap built with `geom_tile()`
#> → heatmap built with `geom_tile()`

heat1 <- ggheatmap(t(small_mat)) +
    theme(axis.text.x = element_text(angle = -60, hjust = 0)) +
    anno_left() +
    align_dendro(aes(color = .panel), k = 3L) +
    anno_right() +
    ggalign(data = rowSums) +
    geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity")

stack_discretev(small_mat, sizes = c(1, 2, 1)) +
    heat1 +
    ggheatmap() +
    theme(axis.text.x = element_text(angle = -60, hjust = 0))
#> → heatmap built with `geom_tile()`
#> → heatmap built with `geom_tile()`

In this way, the width/height of main plot specified in quad_active() or quad_layout()/ggheatmap() won’t work.

stack_discretev(small_mat) +
    ggheatmap(width = unit(2, "null")) + # not work
    theme(axis.text.x = element_text(angle = -60, hjust = 0)) +
    anno_left() +
    align_dendro(aes(color = .panel), k = 3L) +
    anno_right() +
    ggalign(data = rowSums) +
    geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity") +
    ggheatmap(width = unit(2, "null")) + # not work
    theme(axis.text.x = element_text(angle = -60, hjust = 0))
#> → heatmap built with `geom_tile()`
#> → heatmap built with `geom_tile()`

Now that you’ve learned how to combine quad_layout() and stack_layout() in various configurations, you’re ready to explore a new, exciting way to organize and visualize your data: the circle layout. This layout offers a unique, radial perspective that can be particularly useful for visualizing hierarchical data or creating visually engaging plots.