Skip to content

Commit

Permalink
add eheat_anno function
Browse files Browse the repository at this point in the history
  • Loading branch information
Yunuuuu committed Jul 11, 2024
1 parent a7f2205 commit e38e681
Show file tree
Hide file tree
Showing 27 changed files with 770 additions and 552 deletions.
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
^README\.Rmd$
^README\.html$
^\.github$
^README\.zh-cn\.md$
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ License: MIT + file LICENSE
biocViews: Software, Visualization, Sequencing
Encoding: UTF-8
Depends:
ComplexHeatmap,
ggplot2
Imports:
ComplexHeatmap,
grid,
cli,
rlang (>= 1.1.0),
Expand All @@ -34,6 +34,7 @@ Collate:
'eanno.R'
'eheat-package.R'
'eheat.R'
'eheat_anno.R'
'gganno.R'
'ggfit.R'
'ggheat.R'
Expand Down
5 changes: 2 additions & 3 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Generated by roxygen2: do not edit by hand

S3method("[",ExtendedAnnotation)
S3method(eheat_prepare,ExtendedAnnotation)
S3method(eheat_prepare,ExtendedHeatmap)
S3method(eheat_prepare,default)
S3method(eheat_prepare,ggAnno)
S3method(eheat_prepare,ggHeatmap)
S3method(get_guides,default)
Expand All @@ -18,9 +17,9 @@ export(anno_gg2)
export(draw)
export(eanno)
export(eheat)
export(eheat_anno)
export(eheat_decorate)
export(eheat_grob)
export(eheat_prepare)
export(get_guides)
export(gganno)
export(ggfit)
Expand Down
18 changes: 9 additions & 9 deletions R/anno-gg.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#'
#' # anno_gg-panel: clip = "off" -------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg(g, "panel",
#' clip = "off",
#' height = unit(6, "cm"),
Expand All @@ -21,7 +21,7 @@
#'
#' # anno_gg-panel: clip = "on" --------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg(g, "panel",
#' clip = "on",
#' height = unit(6, "cm"),
Expand All @@ -32,7 +32,7 @@
#'
#' # anno_gg-plot ---------------------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg(g, "plot",
#' height = unit(6, "cm"),
#' show_name = FALSE
Expand All @@ -42,7 +42,7 @@
#'
#' # anno_gg-full --------------------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg(g, "full",
#' height = unit(6, "cm"),
#' show_name = FALSE
Expand Down Expand Up @@ -75,7 +75,7 @@ anno_gg <- function(gg, align_with = "full", clip = NULL, gt = NULL,
#' @examples
#' # anno_gg2-panel: margins = NULL -------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg2(g, "panel",
#' margins = NULL,
#' height = unit(6, "cm"),
Expand All @@ -86,7 +86,7 @@ anno_gg <- function(gg, align_with = "full", clip = NULL, gt = NULL,
#'
#' # anno_gg2-panel: margins = "l" --------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg2(g, "panel",
#' margins = "l",
#' height = unit(6, "cm"),
Expand All @@ -97,7 +97,7 @@ anno_gg <- function(gg, align_with = "full", clip = NULL, gt = NULL,
#'
#' # anno_gg2-panel: margins = "r" --------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg2(g, "panel",
#' margins = "r",
#' height = unit(6, "cm"),
Expand All @@ -108,7 +108,7 @@ anno_gg <- function(gg, align_with = "full", clip = NULL, gt = NULL,
#'
#' # anno_gg2-plot ---------------------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg2(g, "plot",
#' height = unit(6, "cm"),
#' show_name = FALSE
Expand All @@ -118,7 +118,7 @@ anno_gg <- function(gg, align_with = "full", clip = NULL, gt = NULL,
#'
#' # anno_gg2-full --------------------
#' ggheat(m,
#' top_annotation = HeatmapAnnotation(
#' top_annotation = eheat_anno(
#' ggplot = anno_gg2(g, "full",
#' height = unit(6, "cm"),
#' show_name = FALSE
Expand Down
5 changes: 3 additions & 2 deletions R/eanno.R
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#' pacakge development, particularly when dealing with internal functions in the
#' package namespace. In addition, all data has been attached in this object.
#' @examples
#' library(grid)
#' x <- 1:10
#' anno <- eanno(
#' draw_fn = function(index, k, n) {
Expand All @@ -56,8 +57,8 @@
#' height = unit(2, "cm")
#' )
#' m <- rbind(1:10, 11:20)
#' eheat(m, top_annotation = HeatmapAnnotation(foo = anno))
#' eheat(m, top_annotation = HeatmapAnnotation(foo = anno), column_km = 2)
#' eheat(m, top_annotation = eheat_anno(foo = anno))
#' eheat(m, top_annotation = eheat_anno(foo = anno), column_km = 2)
#'
#' anno <- eanno(
#' function(index, k, n, self) {
Expand Down
66 changes: 53 additions & 13 deletions R/eheat.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@
#' - `border_gp`: Graphic parameters for the borders. If you want to set
#' different parameters for different heatmap slices, please consider to use
#' `decorate_heatmap_body`.
#' - `cell_fun`: Self-defined function to add graphics on each cell. Seven
#' parameters will be passed into this function: ``j``, ``i``, ``x``, ``y``,
#' ``width``, ``height``, ``fill`` which are column index, row index in
#' ``matrix``, coordinate of the cell, the width and height of the cell and the
#' filled color. ``x``, ``y``, ``width`` and ``height`` are all `grid::unit`
#' objects. Check
#' <https://jokergoo.github.io/ComplexHeatmap-reference/book/a-single-heatmap.html#customize-the-heatmap-body>. You can always use
#' `self` to indicates the matrix attached in this Heatmap.
#' - `layer_fun`: Similar as ``cell_fun``, but is vectorized.
#' - `jitter`: Random shifts added to the matrix. The value can be logical or a
#' single numeric value. It it is ``TRUE``, random values from uniform
#' distribution between 0 and 1e-10 are generated. If it is a numeric
Expand Down Expand Up @@ -151,6 +142,18 @@
#' `magick::filter_types`. The default is ``"Lanczos"``.
#' - `post_fun` A function which will be executed after the heatmap list is
#' drawn.
#' @inheritParams ComplexHeatmap::Heatmap
#' @param cell_fun Self-defined function to add graphics on each cell. Seven
#' parameters will be passed into this function: `j`, `i`, `x`, `y`, `width`,
#' `height`, `fill` which are column index, row index of the `matrix`,
#' coordinate of the cell, the width and height of the cell and the filled
#' color. `x`, `y`, `width` and `height` are all [unit][grid::unit] objects.
#'
#' Check
#' <https://jokergoo.github.io/ComplexHeatmap-reference/book/a-single-heatmap.html#customize-the-heatmap-body>.
#'
#' You can always use `self` to indicates the matrix attached in this Heatmap.
#' @param layer_fun Similar as `cell_fun`, but is vectorized.
#' @param legends_margin,legends_panel A list of
#' [Legends][ComplexHeatmap::Legends-class] objects. `legends_margin` will be
#' added in the `heatmap_legend_list` of
Expand All @@ -170,17 +173,55 @@
#' - `+` or `%v%` append heatmaps and annotations to a list of heatmaps.
#'
#' The constructor function pretends to be a high-level graphic function because
#' the ``show`` method of the `Heatmap-class` object actually plots the
#' the `show` method of the `Heatmap-class` object actually plots the
#' graphics.
#' @return A `ExtendedHeatmap` Object.
#' @examples
#' eheat(matrix(rnorm(81), nrow = 9))
#' @export
#' @name eheat
eheat <- function(matrix, ...,
legends_margin = list(), legends_panel = list()) {
cell_fun = NULL,
layer_fun = NULL,
top_annotation = NULL,
bottom_annotation = NULL,
left_annotation = NULL,
right_annotation = NULL,
legends_margin = list(),
legends_panel = list()) {
matrix <- build_heatmap_matrix(matrix)
out <- ComplexHeatmap::Heatmap(matrix = matrix, ...)
old <- eheat_env_set("current_annotation_which", "column")
on.exit(eheat_env_set("current_annotation_which", old), add = TRUE)
force(top_annotation)
force(bottom_annotation)
eheat_env_set("current_annotation_which", "row")
force(left_annotation)
force(right_annotation)

# we also restore the original annotation `which` value before running
# `ComplexHeatmap::Heatmap`. if we omit this line, the rownames/colnames
# will be strange. It'll affect the action of `anno_text`, which will be
# used to draw heatmap labels. it won't hurt to reset the value twice.
eheat_env_set("current_annotation_which", old)

# ComplexHeatmap::Heatmap will change the function environment of
# `layer_fun` and `cell_fun`. But I don't think this is necessay.
# so here we'll assign the `layer_fun` and `cell_fun` directly after
# creating the heatmap object.
out <- ComplexHeatmap::Heatmap(
matrix = matrix, ...,
layer_fun = NULL, cell_fun = NULL,
top_annotation = top_annotation,
bottom_annotation = bottom_annotation,
left_annotation = left_annotation,
right_annotation = right_annotation
)
if (!is.null(layer_fun)) {
out@matrix_param$layer_fun <- layer_fun
}
if (!is.null(cell_fun)) {
out@matrix_param$cell_fun <- cell_fun
}
out <- methods::as(out, "ExtendedHeatmap")
out@legends_margin <- legends_margin
out@legends_panel <- legends_panel
Expand Down Expand Up @@ -246,7 +287,6 @@ wrap_heat_fn <- function(object, fun_name) {
}
}

#' @importClassesFrom ComplexHeatmap HeatmapAnnotation
#' @importFrom ComplexHeatmap make_layout
#' @export
#' @keywords internal
Expand Down
69 changes: 69 additions & 0 deletions R/eheat_anno.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#' Construct HeatmapAnnotation object
#'
#' This function is similar to the
#' [HeatmapAnnotation][ComplexHeatmap::HeatmapAnnotation] function, but it
#' automatically guesses the `which` argument when combined with the [eheat]
#' function. Additionally, the `eheat_anno` function provides alternative
#' options to set the height(or width) of each individual annotation or adjust
#' the dimensions of the entire set of column/row annotations simultaneously
#' using the `annotation_size` or `size` parameters.
#'
#' @param ... Additional arguments passed to
#' [HeatmapAnnotation][ComplexHeatmap::HeatmapAnnotation].
#' @param annotation_size Height/width of each annotation for column/row
#' annotation.
#' @param size Height/width of the whole annotations for column/row annotation.
#' @param which A string of `"row"` or `"column"`.
#' @return A [HeatmapAnnotation][ComplexHeatmap::HeatmapAnnotation-class]
#' object.
#' @examples
#' # No need to specify which argument if combine with `ggheat` or `eheat`
#' g <- ggplot(mpg, aes(displ, hwy, colour = class)) +
#' geom_point()
#' m <- matrix(rnorm(100), 10)
#' ggheat(m,
#' top_annotation = eheat_anno(
#' ggplot = anno_gg(g, "panel",
#' clip = "on",
#' height = unit(6, "cm"),
#' show_name = FALSE
#' )
#' )
#' )
#' @export
eheat_anno <- function(..., annotation_size = NULL, size = NULL, which = NULL) {
which <- eheat_which(which)
old <- eheat_env_set("current_annotation_which", which)
on.exit(eheat_env_set("current_annotation_which", old), add = TRUE)
if (!rlang::is_named(dots <- rlang::list2(...))) {
cli::cli_abort("all arguments must be named")
}
if (which == "row") {
dots$annotation_width <- dots$annotation_width %||% annotation_size
dots$width <- dots$width %||% size
if (!is.null(.subset2(dots, "annotation_height"))) {
cli::cli_warn(
"cannot set {.arg annotation_height} for row annotation"
)
dots$annotation_height <- NULL
}
if (!is.null(.subset2(dots, "height"))) {
cli::cli_warn("cannot set {.arg height} for row annotation")
dots$height <- NULL
}
} else {
dots$annotation_height <- dots$annotation_height %||% annotation_size
dots$height <- dots$height %||% size
if (!is.null(.subset2(dots, "annotation_width"))) {
cli::cli_warn(
"cannot set {.arg annotation_width} for column annotation"
)
dots$annotation_width <- NULL
}
if (!is.null(.subset2(dots, "width"))) {
cli::cli_warn("cannot set {.arg width} for column annotation")
dots$width <- NULL
}
}
rlang::inject(ComplexHeatmap::HeatmapAnnotation(!!!dots, which = which))
}
1 change: 1 addition & 0 deletions R/ggfit.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#' `lab` in `vp`.
#' - align_with = `"full"`: Draw full ggplot object in `vp`.
#' @examples
#' library(grid)
#' p <- ggplot(data.frame(x = 0:10, y = 0:10), aes(x, y)) +
#' geom_point()
#' outerBox <- viewport(width = unit(125, "mm"), height = unit(150, "mm"))
Expand Down
20 changes: 5 additions & 15 deletions R/prepare.R
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
#' Prepare ExtendedHeatmap
#'
#' @param object A [ExtendedHeatmap][eheat] or [ExtendedAnnotation][eanno]
#' object.
#' @param ... Not used currently.
#' @return An modified `object` with the same class.
#' @examples
#' eheat_prepare(eheat(matrix(rnorm(81), nrow = 9)))
#' @export
eheat_prepare <- function(object, ...) {
UseMethod("eheat_prepare")
}

#' @export
#' @rdname eheat_prepare
eheat_prepare.ExtendedHeatmap <- function(object, ...) {
object
}
#' # eheat_prepare(eheat(matrix(rnorm(81), nrow = 9)))
#' @keywords internal
eheat_prepare <- function(object, ...) UseMethod("eheat_prepare")

#' @export
#' @rdname eheat_prepare
eheat_prepare.ExtendedAnnotation <- function(object, ...,
viewport, heatmap, name) {
object
}
eheat_prepare.default <- function(object, ...) object
Loading

0 comments on commit e38e681

Please sign in to comment.