Mangiola et al., (2020). tidyHeatmap: an R package for modular heatmap production based on tidy principles. Journal of Open Source Software, 5(52), 2472, https://doi.org/10.21105/joss.02472
Please have a look also to
website: stemangiola.github.io/tidyHeatmap
tidyHeatmap
is a package that introduces tidy principles to the creation of information-rich heatmaps. This package uses ComplexHeatmap as graphical engine.
Advantages:
df |> group_by(...)
Function | Description |
---|---|
heatmap |
Plots base heatmap |
add_tile |
Adds tile annotation to the heatmap |
add_point |
Adds point annotation to the heatmap |
add_bar |
Adds bar annotation to the heatmap |
add_line |
Adds line annotation to the heatmap |
layer_point |
Adds layer of symbols on top of the heatmap |
layer_square |
Adds layer of symbols on top of the heatmap |
layer_diamond |
Adds layer of symbols on top of the heatmap |
layer_arrow_up |
Adds layer of symbols on top of the heatmap |
layer_arrow_down |
Add layer of symbols on top of the heatmap |
split_rows |
Splits the rows based on the dendogram |
split_columns |
Splits the columns based on the dendogram |
save_pdf |
Saves the PDF of the heatmap |
To install the most up-to-date version
::install_github("stemangiola/tidyHeatmap") devtools
To install the most stable version (however please keep in mind that this package is under a maturing lifecycle stage)
install.packages("tidyHeatmap")
If you want to contribute to the software, report issues or problems with the software or seek support please open an issue here
The heatmaps visualise a multi-element, multi-feature dataset, annotated with independent variables. Each observation is a element-feature pair (e.g., person-physical characteristics).
element | feature | value | independent_variables |
---|---|---|---|
chr or fctr |
chr or fctr |
numeric |
… |
Let’s transform the mtcars dataset into a tidy “element-feature-independent variables” data frame. Where the independent variables in this case are ‘hp’ and ‘vs’.
<-
mtcars_tidy |>
mtcars as_tibble(rownames="Car name") |>
# Scale
mutate_at(vars(-`Car name`, -hp, -vs), scale) |>
# tidyfy
pivot_longer(cols = -c(`Car name`, hp, vs), names_to = "Property", values_to = "Value")
mtcars_tidy
## # A tibble: 288 × 5
## `Car name` hp vs Property Value[,1]
## <chr> <dbl> <dbl> <chr> <dbl>
## 1 Mazda RX4 110 0 mpg 0.151
## 2 Mazda RX4 110 0 cyl -0.105
## 3 Mazda RX4 110 0 disp -0.571
## 4 Mazda RX4 110 0 drat 0.568
## 5 Mazda RX4 110 0 wt -0.610
## 6 Mazda RX4 110 0 qsec -0.777
## 7 Mazda RX4 110 0 am 1.19
## 8 Mazda RX4 110 0 gear 0.424
## 9 Mazda RX4 110 0 carb 0.735
## 10 Mazda RX4 Wag 110 0 mpg 0.151
## # … with 278 more rows
For plotting, you simply pipe the input data frame into heatmap, specifying:
mtcars
<-
mtcars_heatmap |>
mtcars_tidy heatmap(`Car name`, Property, Value ) |>
add_tile(hp)
## tidyHeatmap says: (once per session) from release 1.2.3 the grouping labels have white background by default. To add color for one-ay grouping specify palette_grouping = list(c("red", "blue"))
mtcars_heatmap
|> save_pdf("mtcars_heatmap.pdf") mtcars_heatmap
We can easily group the data (one group per dimension maximum, at the moment only the vertical dimension is supported) with dplyr, and the heatmap will be grouped accordingly
# Make up more groupings
=
mtcars_tidy_groupings |>
mtcars_tidy mutate(property_group = if_else(Property %in% c("cyl", "disp"), "Engine", "Other"))
|>
mtcars_tidy_groupings group_by(vs, property_group) |>
heatmap(`Car name`, Property, Value ) |>
add_tile(hp)
We can provide colour palettes to groupings
|>
mtcars_tidy_groupings group_by(vs, property_group) |>
heatmap(
`Car name`, Property, Value ,
palette_grouping = list(
# For first grouping (vs)
c("#66C2A5", "#FC8D62"),
# For second grouping (property_group)
c("#b58b4c", "#74a6aa")
)|>
) add_tile(hp)
We can split based on the cladogram
|>
mtcars_tidy heatmap(`Car name`, Property, Value ) |>
split_rows(2) |>
split_columns(2)
We can split on kmean clustering (using ComplexHeatmap options, it is stochastic)
|>
mtcars_tidy heatmap(
`Car name`, Property, Value ,
row_km = 2,
column_km = 2
)
We can easily use custom palette, using strings, hexadecimal color character vector,
|>
mtcars_tidy heatmap(
`Car name`,
Property,
Value,palette_value = c("red", "white", "blue")
)
A better-looking blue-to-red palette
|>
mtcars_tidy heatmap(
`Car name`,
Property,
Value,palette_value = circlize::colorRamp2(
seq(-2, 2, length.out = 11),
::brewer.pal(11, "RdBu")
RColorBrewer
) )
Or a grid::colorRamp2 function for higher flexibility
|>
mtcars_tidy heatmap(
`Car name`,
Property,
Value,palette_value = circlize::colorRamp2(c(-2, -1, 0, 1, 2), viridis::magma(5))
)
::pasilla |>
tidyHeatmapgroup_by(location, type) |>
heatmap(
.column = sample,
.row = symbol,
.value = `count normalised adjusted`
|>
) add_tile(condition) |>
add_tile(activation)
Remove legends, adding aesthetics to annotations in a modular fashion, using ComplexHeatmap
arguments
::pasilla |>
tidyHeatmapgroup_by(location, type) |>
heatmap(
.column = sample,
.row = symbol,
.value = `count normalised adjusted`,
show_heatmap_legend = FALSE
|>
) add_tile(condition, show_legend = FALSE) |>
add_tile(activation, show_legend = FALSE)
“tile”, “point”, “bar” and “line” are available
# Create some more data points
<-
pasilla_plus ::pasilla |>
tidyHeatmap::mutate(act = activation) |>
dplyr::nest(data = -sample) |>
tidyr::mutate(size = rnorm(n(), 4,0.5)) |>
dplyr::mutate(age = runif(n(), 50, 200)) |>
dplyr::unnest(data)
tidyr
# Plot
|>
pasilla_plus heatmap(
.column = sample,
.row = symbol,
.value = `count normalised adjusted`
|>
) add_tile(condition) |>
add_point(activation) |>
add_tile(act) |>
add_bar(size) |>
add_line(age)
We can customise annotation sizes using the grid::unit()
, and the size of their names using in-built ComplexHeatmap
arguments
|>
pasilla_plus heatmap(
.column = sample,
.row = symbol,
.value = `count normalised adjusted`
|>
) add_tile(condition, size = unit(0.3, "cm"), annotation_name_gp= gpar(fontsize = 8)) |>
add_point(activation, size = unit(0.3, "cm"), annotation_name_gp= gpar(fontsize = 8)) |>
add_tile(act, size = unit(0.3, "cm"), annotation_name_gp= gpar(fontsize = 8)) |>
add_bar(size, size = unit(0.3, "cm"), annotation_name_gp= gpar(fontsize = 8)) |>
add_line(age, size = unit(0.3, "cm"), annotation_name_gp= gpar(fontsize = 8))
Add a layer on top of the heatmap
::pasilla |>
tidyHeatmap
# filter
filter(symbol %in% head(unique(tidyHeatmap::pasilla$symbol), n = 10)) |>
heatmap(
.column = sample,
.row = symbol,
.value = `count normalised adjusted`
|>
) layer_point(
`count normalised adjusted log` > 6 & sample == "untreated3"
)
|>
mtcars_tidy heatmap(
`Car name`, Property, Value,
rect_gp = grid::gpar(col = "#161616", lwd = 0.5)
)
|>
mtcars_tidy heatmap(
`Car name`, Property, Value,
cluster_rows = FALSE
)
library(forcats)
## Warning: package 'forcats' was built under R version 4.1.2
|>
mtcars_tidy mutate(`Car name` = fct_reorder(`Car name`, `Car name`, .desc = TRUE)) %>%
heatmap(
`Car name`, Property, Value,
cluster_rows = FALSE
)
|>
mtcars_tidy mutate(`Car name` = fct_reorder(`Car name`, `Car name`, .desc = TRUE)) %>%
heatmap(
`Car name`, Property, Value,
column_dend_height = unit(0.2, "cm"),
row_dend_width = unit(0.2, "cm")
)
|>
mtcars_tidy mutate(`Car name` = fct_reorder(`Car name`, `Car name`, .desc = TRUE)) %>%
heatmap(
`Car name`, Property, Value,
row_names_gp = gpar(fontsize = 7),
column_names_gp = gpar(fontsize = 7),
column_title_gp = gpar(fontsize = 7),
row_title_gp = gpar(fontsize = 7)
)
library(ggplot2)
library(patchwork)
=
p_heatmap |>
mtcars_tidy heatmap(
`Car name`, Property, Value,
show_heatmap_legend = FALSE,
row_names_gp = gpar(fontsize = 7)
)
= tibble(value = 1:10) %>% ggplot(aes(value)) + geom_density()
p_ggplot
wrap_heatmap(p_heatmap) +
+
p_ggplot wrap_heatmap(p_heatmap) +
plot_layout(width = c(1, 0.3, 1))
sessionInfo()
## R version 4.1.0 (2021-05-18)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: CentOS Linux 7 (Core)
##
## Matrix products: default
## BLAS: /stornext/System/data/apps/R/R-4.1.0/lib64/R/lib/libRblas.so
## LAPACK: /stornext/System/data/apps/R/R-4.1.0/lib64/R/lib/libRlapack.so
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=C
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] grid stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] patchwork_1.1.1 ggplot2_3.3.5 forcats_0.5.1 tidyHeatmap_1.6.0
## [5] tidyr_1.1.4 dplyr_1.0.7
##
## loaded via a namespace (and not attached):
## [1] viridis_0.6.2 sass_0.4.0 jsonlite_1.7.2
## [4] viridisLite_0.4.0 foreach_1.5.1 bslib_0.3.1
## [7] assertthat_0.2.1 highr_0.9 stats4_4.1.0
## [10] yaml_2.2.1 pillar_1.6.4 glue_1.5.0
## [13] digest_0.6.28 RColorBrewer_1.1-2 colorspace_2.0-2
## [16] htmltools_0.5.2 pkgconfig_2.0.3 GetoptLong_1.0.5
## [19] purrr_0.3.4 scales_1.1.1 tibble_3.1.6
## [22] farver_2.1.0 generics_0.1.1 IRanges_2.28.0
## [25] ellipsis_0.3.2 withr_2.4.3 BiocGenerics_0.40.0
## [28] cli_3.1.0 magrittr_2.0.1 crayon_1.4.2
## [31] evaluate_0.14 fansi_0.5.0 doParallel_1.0.16
## [34] tools_4.1.0 GlobalOptions_0.1.2 lifecycle_1.0.1
## [37] matrixStats_0.61.0 ComplexHeatmap_2.10.0 stringr_1.4.0
## [40] S4Vectors_0.32.2 munsell_0.5.0 cluster_2.1.2
## [43] compiler_4.1.0 jquerylib_0.1.4 rlang_0.4.12
## [46] iterators_1.0.13 rstudioapi_0.13 rjson_0.2.20
## [49] circlize_0.4.13 labeling_0.4.2 rmarkdown_2.11
## [52] gtable_0.3.0 codetools_0.2-18 DBI_1.1.2
## [55] R6_2.5.1 gridExtra_2.3 knitr_1.36
## [58] fastmap_1.1.0 utf8_1.2.2 clue_0.3-60
## [61] dendextend_1.15.2 shape_1.4.6 stringi_1.7.5
## [64] parallel_4.1.0 Rcpp_1.0.7 vctrs_0.3.8
## [67] png_0.1-7 tidyselect_1.1.1 xfun_0.28