Skip to content

Commit

Permalink
Merge branch 'master' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
z.gu committed Sep 7, 2015
1 parent 12e8549 commit ac4a2fc
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 85 deletions.
Binary file removed .DS_Store
Binary file not shown.
8 changes: 4 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: ComplexHeatmap
Type: Package
Title: Making Complex Heatmaps
Version: 1.4.0
Date: 2015-8-25
Version: 1.4.1
Date: 2015-9-7
Author: Zuguang Gu
Maintainer: Zuguang Gu <[email protected]>
Depends: R (>= 3.1.2), grid, graphics, stats, grDevices
Expand All @@ -18,6 +18,6 @@ Description: Complex heatmaps are efficient to visualize associations
biocViews: Software, Visualization, Sequencing
URL: https://github.com/jokergoo/ComplexHeatmap
License: GPL (>= 2)
Packaged: 2015-8-25 00:00:00 UTC; Administrator
Packaged: 2015-9-7 00:00:00 UTC; Administrator
Repository: Bioconductor
Date/Publication: 2015-8-25 00:00:00
Date/Publication: 2015-9-7 00:00:00
6 changes: 6 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
CHANGES in VERSION 1.4.1

* revised the vignettes

===================================

CHANGES in VERSION 1.4.0

* returned value for `draw` method has been changes
Expand Down
4 changes: 2 additions & 2 deletions R/Heatmap-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,8 @@ Heatmap = function(matrix, col, name,
.Object@matrix_color_mapping = ColorMapping(col_fun = col, name = name, na_col = na_col)
} else {
if(is.null(names(col))) {
if(length(col) == length(unique(matrix))) {
names(col) = unique(matrix)
if(length(col) == length(unique(as.vector(matrix)))) {
names(col) = unique(as.vector(matrix))
.Object@matrix_color_mapping = ColorMapping(colors = col, name = name, na_col = na_col)
} else if(is.numeric(matrix)) {
col = colorRamp2(seq(min(matrix, na.rm = TRUE), max(matrix, na.rm = TRUE), length = length(col)),
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ From left to right, heatmaps are:
7. distance from the DMR to the TSS of the corresponding gene.
8. overlapping between DMRs and enhancers (Color shows how much the DMR is covered by the enhancers).

![example](https://cloud.githubusercontent.com/assets/449218/6862097/1bc46436-d443-11e4-91f5-431bc9210c80.png)
![download](https://cloud.githubusercontent.com/assets/449218/9685180/dddf30c0-531c-11e5-805a-4cc5a36e9197.png)

## OncoPrint

Expand All @@ -95,3 +95,9 @@ With general functionality of **ComplexHeamtap**, you can add more heatmaps / ro
oncoPrint to enphasize sub groups.

![oncoprint](https://cloud.githubusercontent.com/assets/449218/9370313/9c9b6b00-46cf-11e5-9740-c5c2a7a40eb5.png)

## Interact with heatmaps

You can use mouse to select a region on the heatmap, it will return row index and column index which correspond to the selected region.

![download](https://cloud.githubusercontent.com/assets/449218/9685087/456d6276-531c-11e5-9837-2ba8a081ad50.gif)
8 changes: 4 additions & 4 deletions vignettes/s1.introduction.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ to get full use of the package.
There are several vignettes in the package. Each vignette focuses on a specific topic. Following
lists the general topics discussed in these vignettes:

1. [**Making a single Heatmap**](s2.single_heatmap.html)
1. [**Making a Single Heatmap**](s2.single_heatmap.html)

This vignette introduces the basic configuration for making a single heatmap. Similar as other
R functions/packages, the basic usage is quite similar, but there are several unique features
Expand All @@ -89,12 +89,12 @@ lists the general topics discussed in these vignettes:
different levels that split the heatmap.
- The heatmap body itself can be completely self-defined.

2. [**Making a list of heatmaps**](s3.a_list_of_heatmaps.html)
2. [**Making a List of Heatmaps**](s3.a_list_of_heatmaps.html)

This vignette introduces how to concatenate a list of heatmaps and how adjustment is applied to keep
the correspondence of the heatmaps.

3. [**Heatmap annotations**](s4.heatmap_annotation.html)
3. [**Heatmap Annotations**](s4.heatmap_annotation.html)

This vignette introduces the concept of the heatmap annotation and demonstrate how to make simple annotations
as well as complex annotations. Also, the vignette explains the difference between column annotations
Expand All @@ -105,7 +105,7 @@ lists the general topics discussed in these vignettes:
This vignette introduces how to configurate the heatmap legend and annotation legend, also
how to add self-defined legends.

5. [**Heatmap decoration**](s6.heatmap_decoration.html)
5. [**Heatmap Decoration**](s6.heatmap_decoration.html)

This vignette introduces methods to add more self-defined graphics to the heatmaps after the heatmaps
are generated.
Expand Down
29 changes: 15 additions & 14 deletions vignettes/s2.single_heatmap.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,9 @@ of the dendrograms and size of the dendrograms.

```{r cluster_basic}
Heatmap(mat, name = "foo", cluster_rows = FALSE)
Heatmap(mat, name = "foo", show_column_hclust = FALSE)
Heatmap(mat, name = "foo", row_hclust_side = "right")
Heatmap(mat, name = "foo", column_hclust_height = unit(2, "cm"))
Heatmap(mat, name = "foo", show_column_dend = FALSE)
Heatmap(mat, name = "foo", row_dend_side = "right")
Heatmap(mat, name = "foo", column_dend_height = unit(2, "cm"))
```

There are three ways to specify distance metric for clustering:
Expand Down Expand Up @@ -294,7 +294,7 @@ Heatmap(mat, name = "foo", cluster_rows = as.dendrogram(diana(mat)),

In the native `heatmap()` function, dendrograms on row and on column are reordered to let features with larger different
separated more from each other, but according to my experience, the default reordering can not always give nice visualization.
So the reordering for the dendrograms are turned off for `Heatmap()` function.
So by default the reordering for the dendrograms are turned off for `Heatmap()` function.

Besides the default reordering method, you can first generate a dendrogram and apply other reordering
method and then send the reordered dendrogram to `cluster_rows` argument.
Expand All @@ -304,17 +304,17 @@ Compare following three plots:
```{r cluster_dendsort, fig.width = 14}
pushViewport(viewport(layout = grid.layout(nr = 1, nc = 3)))
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 1))
draw(Heatmap(mat, name = "foo", row_hclust_reorder = FALSE, column_title = "no reordering"), newpage = FALSE)
draw(Heatmap(mat, name = "foo", row_dend_reorder = FALSE, column_title = "no reordering"), newpage = FALSE)
upViewport()
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 2))
draw(Heatmap(mat, name = "foo", row_hclust_reorder = TRUE, column_title = "default reordering"), newpage = FALSE)
draw(Heatmap(mat, name = "foo", row_dend_reorder = TRUE, column_title = "applied reordering"), newpage = FALSE)
upViewport()
library(dendsort)
dend = dendsort(hclust(dist(mat)))
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 3))
draw(Heatmap(mat, name = "foo", cluster_rows = dend, row_hclust_reorder = FALSE,
draw(Heatmap(mat, name = "foo", cluster_rows = dend, row_dend_reorder = FALSE,
column_title = "reordering by dendsort"), newpage = FALSE)
upViewport(2)
```
Expand All @@ -341,25 +341,25 @@ Heatmap(mat, name = "foo", cluster_rows = function(m) as.dendrogram(diana(m)),

Clustering can help to adjust order in rows and in columns. But you can still set the order manually by `row_order`
and `column_order`. Note you need to turn off clustering
if you want to set order manually. `row_order` and `column_order` can also be set according to matrix row names and column names.
if you want to set order manually. `row_order` and `column_order` can also be set according to matrix row names and column names if they exist.

```{r manual_order}
Heatmap(mat, name = "foo", cluster_rows = FALSE, cluster_columns = FALSE,
row_order = 12:1, column_order = 10:1)
```

Note `row_reorder` and `row_order` are different. `row_reorder` is applied on the dendrogram. Because for any node in the
Note `row_dend_reorder` and `row_order` are different. `row_dend_reorder` is applied on the dendrogram. Because for any node in the
dendrogram, rotating two leaves gives an identical dendrogram. Thus, reordering the dendrogram by automatically rotating sub-dendrogram
at every node will help to separate elements with more difference to be farther from each other. While `row_order` is
applied on the matrix and dendrograms should be suppressed.
applied on the matrix and dendrograms are suppressed.

## Dimension names

Side, visibility and graphic parameters for dimension names can be set as follows.

```{r dimension_name}
Heatmap(mat, name = "foo", row_names_side = "left", row_hclust_side = "right",
column_names_side = "top", column_hclust_side = "bottom")
Heatmap(mat, name = "foo", row_names_side = "left", row_dend_side = "right",
column_names_side = "top", column_dend_side = "bottom")
Heatmap(mat, name = "foo", show_row_names = FALSE)
Heatmap(mat, name = "foo", row_names_gp = gpar(fontsize = 20))
Heatmap(mat, name = "foo", row_names_gp = gpar(col = c(rep("red", 4), rep("blue", 8))))
Expand All @@ -376,7 +376,7 @@ example in the [**Heatmap Annotation**](s4.heatmap_annotation.html) vignette).

A heatmap can be split by rows. This will enhance the visualization of group separation in the heatmap.
The `km` argument with a value larger than 1 means applying a k-means clustering on rows and clustering
is applied on every k-means clusters.
is applied on every k-means cluster.

```{r k_means}
Heatmap(mat, name = "foo", km = 2)
Expand Down Expand Up @@ -420,7 +420,8 @@ Heatmap(mat, name = "foo", split = paste0("pam", pa$clustering), gap = unit(5, "
Character matrix can only be split by `split` argument.

```{r split_discrete_matrix}
Heatmap(discrete_mat, name = "foo", split = rep(letters[1:2], each = 5))
Heatmap(discrete_mat, name = "foo", col = 1:4,
split = rep(letters[1:2], each = 5))
```

When split is applied on rows, graphic parameters for row title and row names can be specified as same
Expand Down
12 changes: 10 additions & 2 deletions vignettes/s3.a_list_of_heatmaps.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ options(width = 100)

A list of heatmaps can improve visualization of the correspondence between multiple data sources.
In this vignette, we will discuss configurations for making a list of heatmaps and you can
see more real-world examples in the [**Examples**](s7.examples.html) vignette.
see more real-world examples in the [**Examples**](s9.examples.html) vignette.

## Heatmap concatenation

Expand Down Expand Up @@ -157,13 +157,21 @@ ht1 + ht2
`ht_global_opt()` can set graphic parameters for dimension names and titles as global settings.

```{r, fig.width = 10}
ht_global_opt(heatmap_row_names_gp = gpar(fontface = "italic"), heatmap_column_names_gp = gpar(fontsize = 14))
ht_global_opt(heatmap_row_names_gp = gpar(fontface = "italic"),
heatmap_column_names_gp = gpar(fontsize = 14))
ht1 = Heatmap(mat, name = "ht1", column_title = "Heatmap 1")
ht2 = Heatmap(mat, name = "ht2", column_title = "Heatmap 2")
ht1 + ht2
ht_global_opt(RESET = TRUE)
```

Following are global settings supported by `ht_global_opt()`. By this function, you can also control settings
for the legends.

```{r}
names(ht_global_opt())
```

## Retrieve orders and dendrograms

`row_order`, `column_order`, `row_dend` and `column_dend` can be used to retrieve corresponding information from
Expand Down
54 changes: 33 additions & 21 deletions vignettes/s4.heatmap_annotation.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ options(markdown.HTML.stylesheet = "custom.css")
options(width = 100)
```

The annotation graphics actually are quite general. The only common characteristic for column annotation
is that they are aligned to the columns of the heatmap. Here there is a `HeatmapAnnotation` class which is used to
define annotations on columns.
The annotation graphics actually are quite general. The only common characteristic for annotations
is that they are aligned to the columns or rows of the heatmap. Here there is a `HeatmapAnnotation` class which is used to
define annotations on columns or rows.

## Column annotation

Expand Down Expand Up @@ -113,7 +113,7 @@ Heatmap(mat, top_annotation = ha1, bottom_annotation = ha2)
Besides simple annotations, there are complex annotations. The complex annotations are always
represented as self-defined graphic functions. Actually, for each column annotation, there will be a viewport
created waiting for graphics. The annotation function here defines how to put the graphics to
this viewport. The only argument of the function is an index of column which is adjusted by column clustering.
this viewport. The only argument of the function is an index of column which is already adjusted by column clustering.

In following example, an annotation of points is created. Please note how we define `xscale` so that positions
of points correspond to middle points of the columns if the annotation is added to the heatmap.
Expand All @@ -122,16 +122,22 @@ of points correspond to middle points of the columns if the annotation is added
value = rnorm(10)
column_anno = function(index) {
n = length(index)
# since middle of columns are in 1, 2, ..., n and each column has width 1
# then the most left should be 1 - 0.5 and the most right should be n + 0.5
pushViewport(viewport(xscale = c(0.5, n + 0.5), yscale = range(value)))
# since order of columns will be adjusted by clustering, here we also
# need to change the order by `[index]`
grid.points(index, value[index], pch = 16, default.unit = "native")
upViewport() # this is very important in order not to mess up the layout
# this is very important in order not to mess up the layout
upViewport()
}
ha = HeatmapAnnotation(points = column_anno) # here the name is arbitrary
ha
draw(ha, 1:10)
```

There are several annotation generators such as `anno_points()` or `anno_barplot()`
Above code is only for demonstration. You don't realy need to define a points annotation,
there are already several annotation generators provided in the package such as `anno_points()` or `anno_barplot()`
which generate such complex annotation function:

- `anno_points()`
Expand Down Expand Up @@ -162,7 +168,7 @@ ha = HeatmapAnnotation(boxplot = anno_boxplot(mat))
draw(ha, 1:10)
```

You can combine more than one annotations into the object.
You can mix simple annotaitons and complex annotations:

```{r heatmap_annotation_mixed_with_complex, fig.width = 7, fig.height = 2}
ha = HeatmapAnnotation(df = df,
Expand All @@ -174,6 +180,7 @@ draw(ha, 1:10)
```

For some of the `anno_*` functions, graphic parameters can be set by `gp` argument.
Also note how we specify `baseline` in `anno_barplot()`.

```{r heatmap_annotation_anno_gp, fig.width = 7, fig.height = 3}
ha = HeatmapAnnotation(barplot1 = anno_barplot(value, baseline = 0, gp = gpar(fill = ifelse(value > 0, "red", "green"))),
Expand All @@ -184,11 +191,10 @@ draw(ha, 1:10)
```

If there are more than one annotations, you can control height of each annotation by `annotation_height`.
The value of `annotation_height` can either be numeric values or `unit` objects. But when you specify the
height to the `unit` objects, you should make sure the sum of heights does not exceed the height of the
annotations shown in the heatmap.
The value of `annotation_height` can either be numeric values or `unit` objects.

```{r, fig.width = 7, fig.height = 3}
# set annotation height as relative values
ha = HeatmapAnnotation(df = df, points = anno_points(value), boxplot = anno_boxplot(mat),
col = list(type = c("a" = "red", "b" = "blue"),
age = colorRamp2(c(0, 20), c("white", "red"))),
Expand All @@ -197,6 +203,7 @@ draw(ha, 1:10)
```

```{r, fig.width = 7, fig.height = 3}
# set annotation height as absolute units
ha = HeatmapAnnotation(df = df, points = anno_points(value), boxplot = anno_boxplot(mat),
col = list(type = c("a" = "red", "b" = "blue"),
age = colorRamp2(c(0, 20), c("white", "red"))),
Expand All @@ -205,11 +212,13 @@ ha = HeatmapAnnotation(df = df, points = anno_points(value), boxplot = anno_boxp
draw(ha, 1:10)
```

With the annotation, you can assign in to the heatmap either by `top_annotation` or `bottom_annotation`.
Also you can control the size of total column annotations by `top_annotation_height` and `bottom_annotation_height`.
If the annotation has proper size, it would be helpful to add axis on it. `anno_points()`, `anno_barplot()`
and `anno_boxplot()` support axes. Please note we didn't allocate space for axes particularly,
we only assume there are empty spaces for showing axes.
With the annotation constructed, you can assign to the heatmap either by `top_annotation` or `bottom_annotation`.
Also you can control the size of total column annotations by `top_annotation_height` and `bottom_annotation_height`
if the height of the annotations are relative values.

If the annotation has proper size (high enough), it would be helpful to add axis on it. `anno_points()`, `anno_barplot()`
and `anno_boxplot()` support axes. Please note we didn't pre-allocate space for axes particularly,
we only assume there are already empty spaces for showing axes.

```{r add_annotation}
ha = HeatmapAnnotation(df = df, points = anno_points(value),
Expand All @@ -232,13 +241,13 @@ Heatmap(mat, name = "foo", top_annotation = ha)
You can suppress some of the annotation legend by specifying `show_legend` to `FALSE` when creating the `HeatmapAnnotation` object.

```{r annotation_show}
ha = HeatmapAnnotation(df = df, show_legend = FALSE,
ha = HeatmapAnnotation(df = df, show_legend = c(FALSE, TRUE),
col = list(type = c("a" = "red", "b" = "blue"),
age = colorRamp2(c(0, 20), c("white", "red"))))
Heatmap(mat, name = "foo", top_annotation = ha)
```

More types of annotations which show data distribution in corresponding rows and columns are supported
More types of annotations which show data distribution in corresponding columns are supported
by `anno_histogram()` and `anno_density()`.

```{r annotation_more, fig.height = 10, fig.width = 7}
Expand All @@ -253,7 +262,7 @@ Text is also one of the annotaiton graphics. `anno_text()` supports adding text
function, it is easy to simulate column names with rotations.
Note you need to calcualte the space for the text annotations by hand and the package doesn't garentee
that all the rotated text are shown in the plot (In following figure, if row names and legend are not drawn,
'C10C10C10' will show completely).
'C10C10C10' will show completely, but there are some tricks which can be found in the [**Examples**](s9.examples.html) vignette).

```{r rotated_column_names}
long_cn = do.call("paste0", rep(list(colnames(mat)), 3)) # just to construct long text
Expand All @@ -273,7 +282,7 @@ ha = HeatmapAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")),
draw(ha, 1:12)
```

There is a shortcut function `rowAnnotation()` which is same as `HeatmapAnnotation(..., which = "row")`.
There is a helper function `rowAnnotation()` which is same as `HeatmapAnnotation(..., which = "row")`.

```{r, eval = FALSE}
ha = rowAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")), width = unit(1, "cm"))
Expand Down Expand Up @@ -310,8 +319,10 @@ draw(ha_combined, 1:12)
Essentially, row annotations and column annotations are identical graphics, but in practice,
there is some difference. In **ComplexHeatmap** package, row annotations have the same place as the heatmap
while column annotations are just like accessory components of heatmaps. The idea here is that row annotations
can be shared by all the heatmaps in the list. For row annotations, similar
can be corresponded to all the heatmaps in the list while column annotations can only be corresponded to its own heatmap.
For row annotations, similar
as heatmaps, you can append the row annotations to heatmap or heatmap list or even row annotation object itself.
The order of elements in row annotations will be adjusted by the clustering of heatmaps.

```{r heatmap_list_with_row_annotation, fig.width = 9}
ha = rowAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")),
Expand Down Expand Up @@ -344,7 +355,7 @@ Since only row clustering and row titles for the main heatmap are kept, they can
of the plot by setting `row_hclust_side` and `row_sub_title_side`:

```{r heatmap_list_hclust_title_side}
draw(ha + ht1, row_hclust_side = "left", row_sub_title_side = "right")
draw(ha + ht1, row_dend_side = "left", row_sub_title_side = "right")
```

### Self define row annotations
Expand All @@ -359,6 +370,7 @@ row_anno = function(index) {
n = length(index)
pushViewport(viewport(xscale = range(value), yscale = c(0.5, n + 0.5)))
grid.rect()
# recall row order will be adjusted, here we specify `value[index]`
grid.points(value[index], seq_along(index), pch = 16, default.unit = "native")
upViewport()
}
Expand Down
Loading

0 comments on commit ac4a2fc

Please sign in to comment.