--- title: "Scales and Facets" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Scales and Facets} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(ggalign) ``` ```{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))) ``` ## Scales Scales are handled as the usual in ggplot2, but for position scales, `limits` cannot be setted, and the internal will always reset it as the default. This is required to align the layout and annotation. ```{r} ggheatmap(small_mat) + scale_x_continuous(limits = c(0, 0)) ``` `breaks` and `labels` in the position scales are handled in a similar manner of discrete scale, thought you can provide as a continuous scale. ### breaks `breaks` should be one of: - `NULL` for no breaks - `waiver()` for the default breaks (the full data index or `NULL` if no data names and `labels` is `waiver()`) - A character vector of breaks (rownames / colunames of the matrix). - A numeric vector of data index. - A function that takes the data limits or the data index as input and returns breaks as output. Also accepts rlang lambda function notation. ```{r} ggheatmap(small_mat) + scale_x_continuous(breaks = NULL) ``` ```{r} ggheatmap(small_mat) + scale_x_continuous() ``` ```{r} no_names <- small_mat colnames(no_names) <- NULL ggheatmap(no_names) + scale_x_continuous() ``` ```{r} ggheatmap(small_mat) + scale_x_continuous(breaks = c("column3", "column5")) ``` ```{r} ggheatmap(small_mat) + scale_x_continuous(breaks = 5:6) ``` ### labels `labels` should be one of: - `NULL` for no labels - `waiver()` for the default labels (data names) - A character vector giving labels (must be same length as breaks) - An expression vector (must be the same length as breaks). See `?plotmath` for details. - A function that takes the data names (or breaks if data has no names) as input and returns labels as output. This can be also a rlang lambda function. ```{r} ggheatmap(small_mat) + scale_x_continuous(labels = NULL) ``` ```{r} ggheatmap(small_mat) + scale_x_continuous() ``` ```{r} ggheatmap(small_mat) + scale_x_continuous(labels = letters[seq_len(ncol(small_mat))]) ``` ```{r} ggheatmap(small_mat) + scale_x_continuous(breaks = c(3, 5), labels = c("a", "b")) ``` ### data ordering Both `breaks` and `labels` should be provided in the original scale of the raw matrix, the internal will reorder them accordingly if you reorder the heatmap rows/columns. `align_reorder` will reorder the heatmap rows/columns based on the weights returned from `fun` argument. Here we reorder the heatmap columns by the means. We provide the labels in the original order here, the layout will reorder them. ```{r} index <- order(colMeans(small_mat)) xlabels <- letters[seq_len(ncol(small_mat))] print(xlabels[index]) ggheatmap(small_mat) + scale_x_continuous(labels = xlabels) + hmanno("t") + align_reorder() ``` ### discrete or continuous `breaks` and `labels` argument will work the same in both discrete scale and continuous scale. But note it's hard to match all discrete scale limits, for sometimes, you should manually specify the `expand` argument. In the following example, we must add `expand` argument to match the heatmap and the hierarchical clustering tree. ```{r} ggheatmap(small_mat) + scale_x_discrete(breaks = c(3, 5), labels = c("a", "b")) + hmanno("t") + align_dendro() + scale_x_discrete() ``` ```{r} ggheatmap(small_mat) + scale_x_discrete(breaks = c(3, 5), labels = c("a", "b")) + hmanno("t") + align_dendro() + scale_x_discrete(expand = expansion(add = 0.5)) ``` Indeed, you can use the default scale for the dendrogram directly. The layout always sets the appropriate limits for the continuous scale. ```{r} ggheatmap(small_mat) + scale_x_discrete(breaks = c(3, 5), labels = c("a", "b")) + hmanno("t") + align_dendro() ``` One useful feature of the discrete scale is handling ambiguous orientation in geoms. Some geoms, like `ggplot2::geom_bar()` and `ggplot2::geom_boxplot()`, use the discrete axis as the main orientation, but by default, we use the continuous scale. For horizontal layouts (including left and right heatmap annotations), you must manually provide the `orientation` argument for these geoms or set the discrete scale. In the following example, `geom_bar` won't work since the ambiguous orientation. ```{r} ggheatmap(small_mat) + hmanno("l") + ggalign() + geom_bar(aes(x = value), stat = "identity") + theme(axis.text.x = element_text(angle = -60, hjust = 0)) ``` Try to provide the `orientation` argument or set the scale into discrete. ```{r} ggheatmap(small_mat) + hmanno("l") + ggalign() + geom_bar(aes(x = value), stat = "identity", orientation = "y") + theme(axis.text.x = element_text(angle = -60, hjust = 0)) ``` ```{r} ggheatmap(small_mat) + hmanno("l") + ggalign() + geom_bar(aes(x = value), stat = "identity") + scale_y_discrete() + theme(axis.text.x = element_text(angle = -60, hjust = 0)) ``` ## Facets When working with facets, manual configuration of panel using the `facet_*` function is not possible since the internal will use `facet_grid` to set the row/column groups defined by `align_*()` functions. However, you can provide `facet_grid()` or `facet_null()` (if no panel) to control other arguments except `rows` and `cols`. A common usage case is to change the panel strip text. The default theme in this package will always remove the panel strip text, you can override this behaviour with `theme(strip.text = element_text())`. This allows us to add the panel title in the plot area. ```{r} ggheatmap(small_mat) + facet_grid(labeller = labeller(.column_panel = function(x) letters[as.integer(x)])) + theme(strip.text = element_text()) + hmanno("top") + align_kmeans(centers = 3L) ``` ## Session information ```{r} sessionInfo() ```