Complex heatmap visualization

Abstract Heatmap is a widely used statistical visualization method on matrix‐like data to reveal similar patterns shared by subsets of rows and columns. In the R programming language, there are many packages that make heatmaps. Among them, the ComplexHeatmap package provides the richest toolset for constructing highly customizable heatmaps. ComplexHeatmap can easily establish connections between multisource information by automatically concatenating and adjusting a list of heatmaps as well as complex annotations, which makes it widely applied in data analysis in many fields, especially in bioinformatics, to find hidden structures in the data. In this article, we give a comprehensive introduction to the current state of ComplexHeatmap, including its modular design, its rich functionalities, and its broad applications.


INTRODUCTION
Heatmap is a popular method for visualizing matrix-like data by taking colors as the aesthetic elements.There are two major categories of heatmap visualization: spatial heatmap and grid heatmaps [1].The first category visualizes spatially distributed patterns, such as the global temperature distribution across the world, or the click activities on a web page from users.The so-called choropleth map also utilizes heatmaps to visualize certain characteristics in geographic areas within a region.The second category is purely a rectangular layout of colored grids, where the two dimensions correspond to two types of variables.In most cases, rows and columns of a heatmap are reordered by certain methods so that subsets of rows and columns showing similar patterns are grouped closely on the heatmap.The reordering is mostly applied by hierarchical clustering, thus the grid heatmap is also called the cluster heatmap.In this article, we only discuss the grid heatmap.
Heatmap visualization can be traced back to the 19th century when it was used to visualize various social statistics in different districts in Paris [2].However, as a statistical visualization method, it has only been widely used when it was applied in bioinformatics since the 1990s.Since the very early paper on heatmap visualization on gene expression datasets was published in 1998 [3], heatmap has been a standard tool for visualizing omics-level data, for example, gene expression or DNA methylation datasets that are represented as matrices.Nowadays, heatmap is applied in genomics for more specific studies, for example, to visualize genome-level regulation on three-dimensional (3D) scales [4], DNA methylation signals in the binned genome [5], or enrichment of a certain type of genomic signals around a specific genomic feature [6].Rectangular layout is the most used for heatmap visualization; moreover, there are also other layouts, such as the circular layout [7], the spiral layout [8], and the Hilbert curve layout [9].They are useful in specific scenarios.
R is a popular programming language for data analysis and visualization.In R, there are a number of packages that make heatmaps.The function heatmap() from the stats package is the most fundamental one, but with very limited functionality.The function heatmap.2()from the gplots package is an enhanced version of heatmap() which supports more graphics on heatmaps, such as color legends with value distributions and trace lines showing the difference of values to the column or row medians.The function geom_tile() from the ggplot2 package [10] also provides a simple implementation of heatmaps.There are also packages that provide more flexible controls on heatmaps, such as the function pheatmap() from the pheatmap package, and the function aheatmap() from the NMF package [11].
As data emerge fast in sizes and dimensions nowadays, especially in the field of genomics, an efficient visualization for integrative analysis or multi-omics analysis is urgently needed to associate multiple types of data for easily revealing relationships between multiple objects.From the aspect of heatmap visualization, it reflects two points.The first one is the support of heatmap annotations, which contain extra information to associate with the main heatmap.For example, in a typical heatmap visualization on gene expression data where rows are genes and columns are patients, it is common that patients have clinical metadata available, such as age, gender, or whether the patient has certain DNA mutations.With annotations attached to the heatmap, it is easy to identify, for example, whether a group of genes showing high expression correlates to a certain age interval, or whether they have specific types of DNA mutations.heatmap() and heatmap.2()only support a single heatmap-like annotation for one numeric or character vector.pheatmap() and aheamtap() allow multiple heatmap-like annotations for corresponding more information to the heatmap.The superheat [12] and heatmap3 [13] packages support more types of graphics for annotations, such as points or lines that are able to make more accurate visual representations of the data.The second point of visualizing multiple sources of information is to directly apply "complex heatmap visualization" by simultaneously linking multiple heatmaps to make it straightforward to compare patterns shared between heatmaps.For example, in our previous study [6], we applied complex heatmap visualization on data of gene expression, DNA methylation, and various histone modifications to reveal general transcriptional regulation patterns among multiple human tissues.To implement both complex annotation and heatmap visualization, we have developed an advanced heatmap package named ComplexHeatmap [14].It supports not only the basic annotation graphics as in other packages, but also a variety of extra complex annotation graphics such as violin plot or horizon chart, and it even allows users to self-define their own annotation graphics.ComplexHeatmap provides a simple syntax to link multiple heatmaps and annotations where rows or columns of all heatmaps are adjusted simultaneously.The simplicity of its user interface and comprehensiveness of its functionalities make Complex-Heatmap widely used in the bioinformatics community to reveal interesting patterns from data that are potentially biologically meaningful.
The ComplexHeatmap project was started in 2015 and the corresponding paper was published in 2016 [14].Since then, it has become a popular tool in the bioinformatics field.It has been downloaded more than 500k times and 104 other CRAN/Bioconductor packages have direct dependencies on it (data collected on June 22, 2022).ComplexHeatmap has been applied to build comprehensive visualization in a wide range of biology studies, such as on cancers [15], COVID-19 [16], single cells [17], immunology [18], as well as in other fields, such as oceanology [19] and ecology [20].Continually in the past 6 years, ComplexHeatmap has been actively maintained with many new features added.We have also reformatted the documentation as a comprehensive book (https://jokergoo.github.io/ComplexHeatmap-reference/book/).In this article, we will give a comprehensive introduction on the current state of ComplexHeatmap, including its modular design, its rich functionalities, and its broad applications.

Modular design
ComplexHeatmap is designed in a modular and objectoriented way.There are three major classes defined in ComplexHeatmap: the Heatmap class that defines a complete heatmap with multiple components, the HeatmapAnnotation class that defines a list of annotations with specific graphics, and the HeatmapList class that manages a list of heatmaps and heatmap annotations.
The heatmap is the basic unit of complex heatmap visualization.A single heatmap is composed of the heatmap body and various heatmap components (Figure 1A).The heatmap body is a two-dimensional arrangement of grids where each grid corresponds to a specific value in the input matrix.The heatmap components contain titles, dendrograms, labels for matrix rows and columns, and heatmap annotations.These components can be optionally put on the four sides of the heatmap body and each component is managed by a specific method that is defined for the Heatmap object.Additionally, the heatmap body can be split into rows and columns, for example, by categorical variables, into slices.Dendrograms, heatmap labels, and annotations are then reordered or split accordingly.
Heatmap annotations contain additional information that associates with rows or columns of the heatmap.
ComplexHeatmap provides rich support for setting different annotations and defining new annotation graphics.The annotations can be put on the four sides of the heatmap as its components, and they can also be arranged independently to be concatenated to the heatmaps.A HeatmapAnnotation object contains a list of single annotations, which are defined by the Single-Annotation class (Figure 1B).Every single annotation contains a specific type of graphic, which is further defined by the AnnotationFunction class.The Annota-tionFunction class provides a flexible way to define new annotation graphics, which can be automatically reordered and split according to the main heatmap.
The main feature of ComplexHeatmap is it supports concatenating a list of heatmaps and annotations horizontally or vertically to visualize associations between different data sources.The HeatmapList class is a container of a list of heatmaps and annotations (Figure 1C) and it automatically adjusts the correspondence of rows or columns in multiple heatmaps and annotations.

Single heatmap
ComplexHeatmap provides rich functionalities for configuring single heatmaps.The constructor function Heatmap() makes a single heatmap and it returns an object in the Heatmap class.The only mandatory argument in Heatmap() is a matrix, either in numeric or character.Heatmap() provides a large number of additional arguments for customizing heatmaps.Besides the common functionalities also available in other heatmap packages, Heatmap() has these unique features listed in the following subsections.

Flexible controls of clustering and reordering
In routine data analysis procedures, the matrix for heatmap visualization is normally accompanied by hierarchical clustering, so that features with similar patterns are grouped closely and they can be easily identified from the colors on heatmap.In Heatmap(), the hierarchical clustering can be specified in various ways: (1) by a predefined distance method, such as "euclidean" or "Pearson," (2) by a distance function that calculates the pairwise distance between two vectors or directly from a matrix, (3) by a clustering function that takes a matrix as input and returns a dendrogram object, and ( 4) by a clustering object, for example, a hclust or a dendrogram object, or an object that can be coerced to a dendrogram object by a proper as.dendrogram() function.The last method is especially useful because it makes it possible to use dendrograms generated or edited by other packages.For example, with the dendextend package [21], dendrogram branches can be rendered with different colors to highlight sub-dendrograms, or specific symbols can be added to dendrogram nodes, and then the rendered dendrograms can be seamlessly integrated with Heatmap() (Figure 2A).A dendrogram is normally represented as a binary tree where the order of two branches is assigned arbitrarily on a node.Rotating the two branches on a node does not change its mathematical representation, but it affects the global ordering of dendrogram leaves.Thus, a proper way to rotate dendrogram branches, or in other words, to reorder the dendrogram, helps to move matrix rows or columns with similar patterns closer to each other in the heatmap to improve the visualization.By default, Heatmap() uses reorder.dendrogram() to reorder the dendrogram based on the mean of the submatrix for the dendrogram branches.For example, on every node in a dendrogram, one branch with a smaller mean value is always put on the left of the node.Heatmap() also accepts dendrogram objects, thus other dendrogram reordering methods can be easily integrated by first generating dendrogram objects for rows or columns, then applying a specific dendrogram reordering method, such as from the dendsort package [22], and finally sending them to Heatmap().
Note hierarchical clustering is just a special way to reorder rows and columns of a heatmap.Other methods that calculate row and column orders of a matrix can also be integrated.Heatmap() allows users to set numeric or character indices to reorder heatmaps.Examples of popular packages for ordering matrices are seriation [23] and biclust [24].

Split heatmap
Heatmap splitting is an efficient way of highlighting group-wise patterns.Due to the hierarchical clustering procedure, when a new leaf or a sub-dendrogram is added to the dendrogram, the calculation is only based on the items that have already been in the dendrogram, while not on all the items in the matrix.This weakens the visualization power in some datasets if they only have intermediate levels of group-wise differences.A presplitting on heatmaps can greatly improve the distinguishability of group-wise patterns.ComplexHeatmap provides various ways for splitting heatmap into "slices" into both rows and columns (Figure 2A,B): (1) Set a number of groups for k-means clustering, where it also supports repeatedly running k-means clustering to obtain a consensus k-means clustering results to reduce the effect of randomness; (2) Set a categorical variable that contains predefined grouping information.The variable can be a vector or a data frame, then the heatmap is split by all combinations of levels in the categorical variable; (3) If the hierarchical clustering is already applied, the splitting can be specified as a single number so that cutree() is internally applied to cut the dendrogram.For the first two splitting methods, if clustering is turned on, hierarchical clustering is first performed within every heatmap slice, then a second clustering is applied over heatmap slices based on their means to show the slice-level hierarchical relations.
As an example, the heatmap in Figure 2C includes genes that have significant differential expression in a glioblastoma cohort [25] with four subgroups (as the top annotation).The four subgroups are predicted by consensus clustering where the classification is very stable [26].The stable classification is also supported by a t-SNE analysis where the four subgroups are well separated (Supporting Information: Figure 1).However, if the hierarchical clustering is directly applied by pooling all samples, the four subgroups are not well separated as expected, whereas some samples in subgroups 3 (blue) and 4 (purple) are mixed.In Figure 2D, with the same matrix, columns are first split by the classification, then the hierarchical clustering is applied within each column slice separately.As a comparison, it indeed improves the visualization of group-wise patterns.Also, in Figure 2D, rows are additionally split by k-means clustering.Now it is very straightforward to observe the expression patterns of subgroup-specific signature genes.

Render heatmap body as raster images
When we produce so-called "high-quality figures," normally the figures are saved as vector graphics in the formats of, for example, pdf or svg.The vector graphics store the details of every single graphic element, thus if a heatmap made from a huge matrix is saved as vector graphics, the file size would be very big and the complete image would take a long time to be rendered by image viewers.Due to the limited size and resolution of the graphics device, neighboring grids from the heatmap are actually merged into single pixels for large heatmaps.Thus, it is not necessary to keep all the details of the huge heatmap and proper methods should be applied to efficiently reduce the original image.
Rasterization is a method to convert an image into a matrix of colors in red-green-blue (RGB) values.Let us assume a matrix for heatmap has n r rows and n c columns.When it is drawn on a certain graphics device, for example, an on-screen device, the corresponding heatmap body uses p r and p c pixels for the rows and columns, respectively.When n r > p r and/or n c > p c , multiple values in the matrix are mapped to single pixels where n r and/or n c can be reduced to be equal to p r and/ or p c .ComplexHeatmap provides three methods to reduce the graphics in the heatmap body by rasterization: (1) First the heatmap body is written as a temporary png image with p r × p c resolution, then the temporary image is read as a raster object and filled back to the heatmap body.In this way, the image reduction is performed on the png device.( 2) The original matrix is first reduced to the size of p r × p c so that one single value in the reduced matrix can correspond to a distinct pixel.The reduction on the matrix can be applied with a specific method, such as taking the mean or a random value from the submatrices.(3) A temporary image with resolution n r × n c is first generated, then the magick package is used to reduce the image to the size p r × p c , finally, the reduced image is read as a raster object and filled into the heatmap body.The magick package provides a large number of methods for resizing the image and they are all supported in ComplexHeatmap.In "Section 2.8 Heatmap as raster image" of the ComplexHeatmap book, there are detailed visual comparisons of different image reduction methods.

Customize heatmap
By default, heatmap bodies are composed of a twodimensional organization of colored grids or cells.Complex-Heatmap allows users to customize heatmap bodies by adding new layers of graphics.Arguments cell_fun and layer_fun in Heatmap() can be used to add selfdefined graphics to heatmap cells when heatmap is drawing (Figure 2A).The two arguments are basically the same except layer_fun is a vectorized version of cell_fun, which makes the drawing faster if the heatmap body is large.More generally, decorate_*() family functions, for example, decorate_annotation(), add graphics to any heatmap component after the heatmap has been drawn.Every heatmap component has its own plotting region (or viewport) and they are still recorded after the heatmap is drawn.decorate_*() can go back to a specific viewport and add self-defined graphics there afterward.
As will be introduced in later sections, the 3D heatmap, the oncoPrint, and the UpSet plot are internally implemented with layer_fun; the density heatmap and enriched heatmap are partially enhanced by implementing decorate_heatmap_body().

Flexible controls of colors and legends
In a heatmap, colors are the major aesthetic elements mapping to data.ComplexHeatmap allows exact mapping between colors and values in the matrix by a color mapping function by specifying breaks and corresponding colors, then remaining colors are linearly interpolated in the corresponding intervals in a specific color space.For example, users can define a color mapping function that is symmetric to zero, which is useful for identifying the expression of up-regulated and downregulated genes, or users can define the same color mapping functions for different heatmaps to make colors comparable between them.It also allows flexible configurations on heatmap legends, such as multi-color scheme legends and legends with self-defined graphics.We kindly refer readers to "Chapter 5. Legends" in the ComplexHeatmap book for more demonstrations.

Heatmap annotations
Heatmap annotations are important components of a heatmap.It not only shows additional information associated with heatmap rows and columns, but also allows visualizing with more types of graphics.ComplexHeatmap provides flexible support for built-in annotations as well as new selfdefined annotation graphics.In Figure 3A, we demonstrate part of annotation graphics that are by default supported in ComplexHeatmap (from left to right): Alternatively, the distributions can be visualized by normal density plots or heatmaps.12. Joy plot annotation.The peaks can be extended into neighbors' plotting regions.13.Horizon chart annotation.A horizon chart is a visualization method that vertically splits an area chart with uniform size, then the bands are layered on top of each other [27].
All built-in annotation graphics are implemented by annotation functions named with anno_ prefix, for example, anno_points() for points annotation.Besides the above-listed annotations, ComplexHeatmap supports more complex ones.For example, there is a "mark annotation" by anno_mark(), which draws labels for a subset of rows or columns where the labels are shifted from their original positions to get rid of overlapping, and lines are drawn to connect labels to their original rows or columns (Figure 3B).There is also a "link annotation" by anno_link(), which links plotting regions to subsets of a heatmap.The link annotation provides a general solution to associate more self-defined graphics to correspond to heatmap rows or columns.In Figure 3C, three ggplot2 plots are created that visualize distributions of values in the three column groups but only in the selected subsets of rows.In Figure 3D, a list of words is associated with each row group where the font sizes correspond to the importance of the words.This has been specifically implemented with the function anno_textbox(), and it has been used to summarize the biological functions of genes in the simplifyEnrichment package [28].
The constructor function HeatmapAnnota- tion() accepts multiple annotations specified as name-value pairs.Simple annotations are specified as vectors, matrices, or a data frame.Other annotations should be specified via functions anno_*().An example with four annotations is demonstrated as follows.Row annotations should be set with one additional argument which = "row" or with the helper function rowAnnotation().ComplexHeatmap already provides a large number of annotation graphics, nevertheless, ComplexHeatmap provides an interface for creating selfdefined annotation graphics.We kindly refer readers to "Section 3.20 Implement new annotation functions" in the ComplexHeatmap book for more details.

A list of heatmaps
The promising feature of ComplexHeatmap is that it supports concatenating multiple heatmaps and annotations so that it is possible to visualize associations between various sources of information.ComplexHeatmap provides a simple syntax for concatenating heatmaps with the operator +.The expression returns a HeatmapList object and directly printing the Heatmap-List object draws the heatmap.An example usage is as follows: We previously introduced annotations as components of a single heatmap.Here row annotations can also be independently concatenated to the heatmap list, as demonstrated in the code above.Alternatively, which is less used, the heatmap lists can be vertically concatenated with the operator %v%.

HeatmapAnnotation(…)
The number of heatmaps and annotations to be concatenated can be arbitrary.The ordering and splitting of all heatmaps are adjusted by the main heatmap, which is by default the first numeric heatmap, or the other heatmap in the list that is specified by the user.

Visualize associations between DNA methylation and gene expression
Figure 4A demonstrates a complex heatmap visualization on a dataset randomly generated but based on patterns found in unpublished work.It visualizes associations between DNA methylation, gene expression, enhancers, and gene-related information.In heatmaps, each row corresponds to a differentially methylated region (DMR, which is a genomic region showing significantly different methylation between tumor and control samples) or other attributes associated with the corresponding DMR.In Figure 4A, there are the following heatmaps and annotations from left to right: 1.A heatmap of methylation in DMRs. 2. A one-column heatmap showing the direction of differential methylation."Hyper" means the methylation is higher in tumor samples and "hypo" means the methylation is lower in tumor samples.3. A heatmap of gene expression.They are the nearest genes to the DMRs.4. A one-column heatmap of p-values from the Pearson correlation test on methylation in DMRs and expression of associated genes.5.A one-column heatmap of the type of genes, for example, protein-coding genes or lincRNAs?6.A one-column heatmap of the locations of DMRs, for example, in promoters or in intergenic regions?7. A points annotation of the genomic distances between DMRs to transcription start sites (TSSs) of the associated genes.8.A heatmap of the overlap between enhancers and DMRs.The value measures the fraction of a DMR covered by enhancers.
In Figure 4A, the heatmap list is split by the combination of directions of differential methylation and a two-group k-means clustering.The grouping by k-means is to distinguish the high-methylation and low-methylation groups on rows.The complex heatmaps reveal that highly methylated DMRs are enriched in intergenic and intragenic regions, and they rarely overlap with enhancers (row groups "2,hypo" and "2,hyper"), while in contrast, lowly methylated DMRs are enriched in promoters and enhancers (row groups "1,hypo" and "1,hyper").This might imply that enhancers associated with low methylation and methylation changes in enhancers might affect their transcriptional activities on related genes.

Visualize global summary statistics in multi-omics studies
Multi-omics studies integrate data from genomics, transcriptomics, or epigenomics to look for novel associations in biological systems from different levels.Thus, it is important to properly and effectively visualize the potential connections between these different data types.Figure 4B demonstrates one such typical landscape summary visualization where a list of different statistics based on single data types or combinations of multiple data types are aggregated by a list of heatmaps and annotation graphics.Figure 4B is based on a glioblastoma cohort study [29], which studies the epigenomic difference between four subtypes (indexed as 1 to 4 in Figure 4B) with DNA methylation, gene expression, and histone modification data.The study generates four sets of DMRs where each one compares methylation in one subtype against normal samples.Figure 4B    In the heatmap list in Figure 4B, it is straightforward to observe the different features of subgroup-specific DMRs.For example, hyper-DMRs have more negative correlations between methylation and gene expression, and hypo-DMRs are located more in the intergenic regions and inactive chromatin states.To conclude, such visualization provides a powerful bird's-eye view of the global attributes in a complex study.

High-level plots
The flexibility of ComplexHeatmap allows users to implement new high-level graphics on data with matrix-like structures.ComplexHeatmap has already implemented several high-level graphics functions and they are introduced in the following subsections.Note all these functions are basically specific customizations on heatmaps.They are essentially in the Heatmap class and they can be concatenated to general heatmaps and annotations to form complex visualizations.

Density heatmap
To visualize data distributions in a matrix or a list, normally boxplots or violin plots are used.However, when the number of distributions becomes large, boxes or violins would not be efficient visualization methods.The function densityHeatmap() uses colors to map the density values and it is able to visualize a large number of distributions (Figure 5A).In densityHeatmap(), the similarity between distributions can be measured with the Kolmogorov-Smirnov distance.
Three-dimensional heatmap Three-dimensional (3D) visualization is in general not recommended for representing data [30], but it might be helpful for specific scenarios.ComplexHeatmap supports converting a normal heatmap to a 3D heatmap by converting heatmap grids to 3D bars, which are drawn as projections onto the two-dimensional plate.3D heatmaps are drawn with the function Heatmap3D() and it accepts the same set of arguments as Heatmap().The density distributions in Figure 5A can also be visualized as a list of bar plots where bars are represented in 3D (Figure 5B).It is recommended to map both colors and bar heights to data in 3D heatmap visualization.

oncoPrint
The function oncoPrint() visualizes multiple genomic alteration events, for example, single-base mutations (SNVs), fragment insertion or deletions (Indels), or copy number variations (CNVs), in a list of genes and in multiple patients.oncoPrint() provides a general solution where graphics for specific genome alterations can be self-defined (Figure 5C).By default, genes are ordered by their total numbers of alterations, and patients are reordered to show mutual exclusivity in the cohort.As oncoPrint() returns a Heatmap object, it can be concatenated to heatmaps of other genomic datasets, for example, gene expression, to show more complicated genomic associations.

UpSet plot
The UpSet plot [31] provides a more efficient way to visualize intersections in a large number of sets compared to the traditional approach, that is, the Venn Diagram.The function UpSet() in ComplexHeatmap provides an enhanced implementation of the original tool [32].Additionally, UpSet() is capable of working on intersections of genomic regions from multiple lists, which helps to reveal, for example, tissue-specific chromatin modifications (Figure 5D).

Genome-level plots
Genome-level heatmaps are frequently used in genomics studies, for example, for visualizing the global copy number variation profiles [33].The key to making genome-level heatmaps is to bin the genome and to normalize various genomic signals to the genome bins to form matrices, then normal heatmap visualization can be applied to them.In Figure 5E, we demonstrated a genome-level visualization with two heatmaps and multiple additional tracks, which are created as heatmap annotations.

EnrichedHeatmap
An enriched heatmap specifically visualizes the enrichment of a certain type of genomic signal on a list of genomic features of interest [34].For example, how chromatin modifications are enriched around gene TSSs or how DNA is lowly methylated around CGIs.The EnrichedHeatmap package [6] is built upon ComplexHeatmap and it provides a general solution for such spatial relations of two types of genomic features.It also implements a special annotation function anno_enriched() that summarizes the average enrichment over all genomic features.Being unique to other similar tools, it is able to normalize categorical genomic signals such as chromatin segmentations.More importantly, the enriched heatmap is also a Heatmap object, thus it inherits all the features from the Heatmap class, such as heatmap splitting and concatenating to more heatmaps.
F I G U R E 6 A list of enriched heatmaps and normal heatmaps.From the left to right are the heatmaps of chromatin states, DNA methylation, and gene expression.Data are from the Roadmap project.
Figure 6 demonstrates a complex visualization of the distribution of chromatin states and DNA methylation around gene TSSs, as well as the expression of associated genes.The data are from the Roadmap project [35].Heatmaps are split into three groups where TSSs are in active states, bivalent states, and inactive states.Through the heatmaps, it can be easily observed that active TSSs are associated with low methylation and the corresponding genes are highly expressed.Bivalent TSSs, although are also lowly methylated, have a lower expression for the genes.In comparison, inactive TSSs are almost fully methylated and the expression of corresponding genes is normally silenced.

InteractiveComplexHeatmap
ComplexHeatmap only generates static plots.The companion package InteractiveComplexHeatmap [36] can seamlessly convert a static heatmap to an interactive Shiny application where users can interact with the heatmap, for example, by clicking and brushing over heatmaps.This is useful when specific patterns are observed on heatmaps, and detailed information about them can be easily extracted by directly interacting with the heatmaps.The conversion from static heatmaps to interactive ones can be easily done with the function htShiny(), which is called with no argument after the static heatmap is generated.This functionality works for all kinds of heatmaps, as long as they are generated by ComplexHeatmap.Moreover, InteractiveComplexHeatmap provides flexible solutions for customizing the user interface of the interactive heatmap applications as well as for defining the responses to users' actions on heatmaps.

CONCLUSION
Complex heatmap visualization is a powerful way to associate multiple sources of information.In this article, we systematically demonstrated the rich functionalities of the ComplexHeatmap package.We believe Complex-Heatmap will continually be a useful tool for bioinformatics and the general data science field for revealing hidden structures in the data.

1
Modular design of the ComplexHeatmap package.(A) Single heatmap with various heatmap components.(B) Heatmap annotation with a list of single annotations.(C) Heatmap list with global titles and legends.
Demonstration of single heatmaps.(A) Heatmap with both row and column annotations.The columns on the heatmap are split by a three-group k-means clustering and rows are split by combinations of a categorical variable and a two-group k-means clustering.(B) Heatmap with customizations on the heatmap body.Data in Figure (A) and (B) are randomly generated.(C) Heatmap without and (D) with column splitting.The matrix for Figure (C) and (D) is the same.

3
Demonstration of various heatmap annotation graphics.(A) Different annotation graphics are supported in ComplexHeatmap.(B) The mark annotation.(C) The link annotation.(D) The textbox annotation.Data in all four figures are randomly generated.ha = HeatmapAnnotation( foo = runif(10), bar = sample(letters[1:4], 10, replace = TRUE), pt = anno_points(runif(10)), txt = anno_text(month.name[1:10])) visualizes various genomic attributes of DMRs with a list of heatmaps and annotations, additionally split by the direction of methylation change.From left to right in Figure4Bthere are:1.A heatmap of the mean methylation in DMRs in tumor samples and in normal samples.2. A bar plot annotation of the number of DMRs in each category.3.A stacked bar plot annotation of the fractions ofDMRs that show significant correlations to the expression of the nearest genes.

4
Demonstration of complex heatmap list visualization.(A) Visualization of the association between DNA methylation, gene expression, and related genomic features.For simplicity of the figure, it only includes DMRs showing negative correlations to associated genes.(B) Comprehensive visualization of the global summary statistics of an epigenomics study.DMRs, differentially methylated regions.COMPLEX HEATMAP VISUALIZATION | 9 of 15

F
I G U R E 5 Demonstration of high-level plots implemented in ComplexHeatmap.(A) The density heatmap.Values in the first 10 columns are generated from the normal distribution and values in the second 10 columns are generated from the uniform distribution.(B) 3D frequency heatmap.The input matrix is the same as in Figure (A).(C) The oncoPrint.The lung adenocarcinoma carcinoma dataset from cBioPortal is used.Only a subset of genes and patients are used due to the limited figure size.(D) The UpSet plot.The H3K4me3 ChIP-seq peaks from six human tissues are from the Roadmap project.(E) Genome-level multiple-track plot.The data are randomly generated.
4. A stacked bar plot annotation of the distances ofDMRs to the TSSs of the nearest genes.5.A stacked bar plot annotation of the fractions ofDMRs that overlap to genes or intergenic regions.6.A stacked bar plot annotation of the fractions of DMRs that overlap to CpG islands (CGIs) or CGI shores.