In a previous post “Word cloud as heatmap annotation”, I introduced how to make word clouds and attach them to heatmaps as annotations. Here I will introduce a more general solution for making textboxes.
The following new functions are implemented in ComplexHeatmap from version 2.13.1. Now you need to update ComplexHeatmap from GitHub.
First I will demonstrate a low-level grid.*
family function
grid.textbox()
. The function simply accepts a vector of texts. If the col
parameter is not specified in gpar()
, random colors are used.
library(ComplexHeatmap)
set.seed(888)
words = sapply(1:30, function(x) strrep(sample(letters, 1), sample(3:10, 1)))
grid.newpage()
grid.textbox(words, gp = gpar(fontsize = runif(30, min = 5, max = 30)))
max_width
controls the maximal width of the textbox.
grid.newpage()
grid.textbox(words, gp = gpar(col = "red", fontsize = 1:30+5), max_width = unit(9, "in"))
Set round_corners
to TRUE
, also set background graphics parameters:
grid.newpage()
grid.textbox(words, gp = gpar(fontsize = runif(30, min = 5, max = 30)),
background_gp = gpar(fill = "#FFEEEE", lty = 2, col = "grey"), round_corners = TRUE,
padding = unit(c(10, 20, 10, 20), "pt"))
One feature of grid.textbox()
is it can properly handle long phrases or sentences which are composed
by multiple words. By default, long phrases are treated as single words, which means, if there is no
enough space in a line, the whole phrase is moved to the next line.
sentenses = c("This is sentense 1", "This is a long long long long long long long sentense.")
grid.newpage()
grid.textbox(sentenses)
Set word_wrap = TRUE
so that long phrases are wrapped if they are too long:
grid.newpage()
grid.textbox(sentenses, word_wrap = TRUE)
If add_new_line
is set to TRUE
, each phrase is put in a separated line.
grid.newpage()
grid.textbox(sentenses, word_wrap = TRUE, add_new_line = TRUE)
Now we can implement the corresponding annotation function for heatmaps. In ComplexHeatmap,
there is a new annotation function anno_textbox()
. The two major arguments for anno_textbox()
are:
align_to
: It controls how the text boxes are aligned to the heatmap rows. The value can be a categorical vector which have the same length as heatmap rows, or a list of row indices. It does not necessarily include all row indices.text
: The corresponding texts. The value should be a list of texts. To control graphics parameters of texts in the boxes, The value oftext
can also be set as a list of data frames where the first column contains the text, from the second column contains graphics parameters for each text. The column names should be “col”, “fontsize”, “fontfamily” and “fontface”.
library(circlize)
mat = matrix(rnorm(100*10), nrow = 100)
split = sample(letters[1:10], 100, replace = TRUE)
text = lapply(unique(split), function(x) {
data.frame(month.name, col = rand_color(12, friendly = TRUE), fontsize = runif(12, 6, 14))
})
names(text) = unique(split)
split
## [1] "b" "f" "h" "h" "c" "g" "a" "h" "d" "e" "g" "c" "j" "c" "c" "j" "a" "d"
## [19] "i" "h" "a" "i" "g" "a" "b" "e" "i" "a" "c" "h" "j" "j" "b" "c" "c" "e"
## [37] "j" "a" "d" "d" "j" "h" "j" "d" "b" "h" "e" "h" "b" "j" "a" "a" "a" "c"
## [55] "g" "d" "b" "a" "a" "g" "b" "g" "h" "j" "g" "f" "i" "j" "a" "d" "i" "b"
## [73] "c" "b" "f" "e" "h" "c" "a" "c" "a" "j" "h" "e" "e" "a" "j" "h" "a" "d"
## [91] "e" "f" "j" "j" "c" "j" "f" "d" "b" "i"
text[1:2]
## $b
## month.name col fontsize
## 1 January #0E0768FF 9.891577
## 2 February #0C8B21FF 7.416968
## 3 March #2C038DFF 12.242896
## 4 April #2AA00CFF 10.454699
## 5 May #74A80DFF 9.777079
## 6 June #4C089AFF 9.825270
## 7 July #4C008FFF 6.179774
## 8 August #0B7C04FF 7.696559
## 9 September #3A810BFF 10.993755
## 10 October #360078FF 8.168969
## 11 November #980228FF 9.337481
## 12 December #960C3DFF 10.450466
##
## $f
## month.name col fontsize
## 1 January #6E0B9BFF 6.639206
## 2 February #042F7DFF 12.770203
## 3 March #099801FF 9.718325
## 4 April #490E90FF 8.623842
## 5 May #092C79FF 12.441386
## 6 June #0A1274FF 9.944144
## 7 July #051B65FF 13.958028
## 8 August #0A0161FF 6.600719
## 9 September #05833AFF 9.839931
## 10 October #4D7704FF 10.190130
## 11 November #5B098FFF 6.375925
## 12 December #007974FF 10.547464
Heatmap(mat, cluster_rows = FALSE, row_split = split,
right_annotation = rowAnnotation(wc = anno_textbox(split, text))
)
sessionInfo()
## R version 4.2.0 (2022-04-22)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Big Sur/Monterey 10.16
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRlapack.dylib
##
## locale:
## [1] C/UTF-8/C/C/C/C
##
## attached base packages:
## [1] grid stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] circlize_0.4.16 ComplexHeatmap_2.13.1 knitr_1.39
## [4] colorout_1.2-2
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.8.3 highr_0.9 bslib_0.3.1
## [4] compiler_4.2.0 RColorBrewer_1.1-3 jquerylib_0.1.4
## [7] iterators_1.0.14 tools_4.2.0 digest_0.6.29
## [10] clue_0.3-61 jsonlite_1.8.0 evaluate_0.15
## [13] png_0.1-7 rlang_1.0.2 foreach_1.5.2
## [16] cli_3.3.0 magick_2.7.3 yaml_2.3.5
## [19] parallel_4.2.0 blogdown_0.8 xfun_0.31
## [22] fastmap_1.1.0 cluster_2.1.3 stringr_1.4.0
## [25] sass_0.4.1 GlobalOptions_0.1.2 S4Vectors_0.34.0
## [28] IRanges_2.30.0 stats4_4.2.0 R6_2.5.1
## [31] GetoptLong_1.0.5 rmarkdown_2.14 bookdown_0.15
## [34] magrittr_2.0.3 codetools_0.2-18 htmltools_0.5.2
## [37] matrixStats_0.62.0 BiocGenerics_0.42.0 shape_1.4.6
## [40] colorspace_2.0-3 stringi_1.7.6 doParallel_1.0.17
## [43] crayon_1.5.1 rjson_0.2.21