--- title: "Stack Layout" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Stack Layout} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` `stack_layout()` put plots horizontally or vertically. You can also use the alias `ggstack()`. ```{r setup} library(ggalign) ``` ## Input data The data input can be a numeric or character vector, a matrix, and a data frame. Simple vector will be converted into a one column matrix. ```{r setup_data} set.seed(123) small_mat <- matrix(rnorm(81), nrow = 9) rownames(small_mat) <- paste0("row", seq_len(nrow(small_mat))) colnames(small_mat) <- paste0("column", seq_len(ncol(small_mat))) ``` By default, `ggstack()` will create the layout, but no plot will be drawn until you add a plot element: ```{r} ggstack(small_mat) ``` We can add any `align_*()` function to customize the layout or integrate plots into the stack. ```{r} ggstack(small_mat) + align_dendro() ``` ```{r} ggstack(small_mat) + align_kmeans(centers = 3L) + ggalign(data = rowSums) + geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity") + facet_grid(switch = "y") + theme(strip.text = element_text()) + align_dendro(aes(color = branch)) ``` By default, `ggstack()` arranges the plots horizontally. To change the direction to vertical, use the `direction` argument: ```{r} ggstack(small_mat, "v") + align_dendro() ``` >Note that vertical stack take the `x-axis` as the observations, but horizontal stack take the `y-axis` as the observations. ## Data frame Input Unlike `heatmap_layout()`/`ggheatmap()`, data frames are not automatically converted into a matrix within `ggstack()`. When using data frames, be cautious as many `align_*()` functions only accept matrix. If the necessary data is not explicitly provided to an `align_*()` function, the data frame from `ggstack()` will be passed to the function and internally converted into a matrix, which may result in missing values. An exception is the `align_gg()`/`ggalign()` function, which can handle both matrix and data frames. When the input is a matrix (or a simple vector), it will be transformed into a long-format data frame. When the input is a data frame, only the necessary panel and axis information will be added to the data frame. ```{r} ggstack(mtcars) + ggalign(aes(mpg)) + geom_point() ``` Note `align_gg()`/`ggalign()` always applies a default mapping for the parallel axes of the data index within the layout. This mapping is `aes(y = .data$.y)` for horizontal stack and `aes(x = .data$.x)` for vertical stack. So here we only provide mapping for the `x-axis`. For more information on adding plots, refer to the vignette: `vignette("layout-plot")`. ## Heatmap plot Besides the `align_*()` functions, we can also add the `heatmap_layout()`/`ggheatmap()` into the stack layout. ```{r} ggstack(small_mat) + ggheatmap() ``` As mentioned earlier, vertical stacks use the `x-axis` for observations, while horizontal stacks use the `y-axis`. However, heatmap layouts always use the y-axis for observations. When a heatmap layout is added to a vertical stack layout, the inherited data is automatically converted to a matrix and transposed before use. ```{r} ggstack(small_mat, direction = "v") + ggheatmap() ``` Once a heatmap layout is added, any further elements you add will be applied to this heatmap layout. You can include `align_*` elements or any ggplot2 components for the heatmap. ```{r} ggstack(small_mat) + ggheatmap() + scale_fill_viridis_c() ``` If you'd like to add elements to the stack layout rather than the heatmap layout, you can easily switch from the heatmap layout to the stack layout using `stack_active()`. ```{r} ggstack(small_mat) + ggheatmap() + scale_fill_viridis_c() + stack_active() + ggalign(data = rowSums) + geom_bar(aes(value), fill = "red", orientation = "y", stat = "identity") ``` One exception is the heatmap layout itself, which cannot be added to another heatmap layout. Therefore, you can directly add a heatmap layout to the stack layout without using `stack_active()`. ```{r} ggstack(small_mat, "v") + ggheatmap() + ggheatmap() & scale_fill_viridis_c() ``` ## Control sizes A length of 3 sizes should be provided in `ggstack()` when putting a heatmap with flank annotation into the stack layout. For vertical stacks, this means heatmaps with left or right annotations; for horizontal stacks, this means heatmaps with top or bottom annotations. The first size controls the relative width/height of the left or top annotation, the second controls the relative size of the heatmap body width/height, and the third controls the relative width/height of the right or bottom annotation. By default the three rows/columns will have equal sizes. ```{r} ggstack(small_mat, "v") + ggheatmap() + scale_fill_viridis_c() + hmanno("l") + align_dendro(aes(color = .panel), k = 3L) + hmanno("r") + ggalign(data = rowSums) + geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity") + ggheatmap() ``` ```{r} ggstack(small_mat, "v", c(1, 2, 1)) + ggheatmap() + scale_fill_viridis_c() + hmanno("l") + align_dendro(aes(color = .panel), k = 3L) + hmanno("r") + ggalign(data = rowSums) + geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity") + ggheatmap() ``` In this way, heatmap body width/height specified in `hmanno()` or `ggheatmap()` won't work. ```{r} ggstack(small_mat, "v") + ggheatmap() + scale_fill_viridis_c() + hmanno("l") + align_dendro(aes(color = .panel), k = 3L) + hmanno("r") + ggalign(data = rowSums) + geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity") + ggheatmap(.width = unit(2, "null")) ``` By default the flank annotation will fill the whole stack flank, but we can still control the total size of heatmap annotation in `hmanno()`. ```{r} ggstack(small_mat, "v") + ggheatmap() + scale_fill_viridis_c() + hmanno("l", size = unit(2, "cm")) + align_dendro(aes(color = .panel), k = 3L) + hmanno("r") + ggalign(data = rowSums) + geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity") + ggheatmap() ``` You can also use `npc` unit. ```{r} ggstack(small_mat, "v") + ggheatmap() + scale_fill_viridis_c() + hmanno("l", size = unit(0.5, "npc")) + align_dendro(aes(color = .panel), k = 3L) + hmanno("r") + ggalign(data = rowSums) + geom_bar(aes(value, fill = .panel), orientation = "y", stat = "identity") + ggheatmap() ``` ## Session information ```{r} sessionInfo() ```