R/circlize.R

Defines functions circlize_dendrogram

Documented in circlize_dendrogram

# Copyright (C) Tal Galili
#
# This file is part of dendextend.
#
# dendextend is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# dendextend is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
#  A copy of the GNU General Public License is available at
#  http://www.r-project.org/Licenses/
#





#' @title Plot a circlized dendrograms
#' @export
#' @author Zuguang Gu, Tal Galili
#' @description
#' Plot a circlized dendrograms using the circlize package (must be installed for the function to work).
#'
#' This type of plot is also sometimes called fan tree plot (although the name fan-plot is also used for a different
#' plot in time series analysis), radial tree plot, polar tree plot, circular tree plot, and probably other names as well.
#'
#' An advantage for using the circlize package directly is for plotting a
#' circular dendrogram so that you can add more graphics for the elements
#' in the tree just by adding more tracks using \link[circlize]{circos.track}.
#'
#' @param dend a \link{dendrogram} object
#' @param facing Is the dendromgrams facing inside to the circle or outside.
#' @param labels logical (TRUE) - should the labels be plotted as well.
#' @param labels_track_height a value for adjusting the room for the labels.
#' It is 0.2 by default, but if NULL or NA, it will adjust automatically based on
#' the max width of the labels. However, if this is too long, the plot will give an error:
#'       Error in check.track.position(track.index, track.start, track.height) :
#'       not enough space for cells at track index '2'.
#' @param dend_track_height a value for adjusting the room for the dendrogram.
#'
#' @param ... Ignored.
#'
#' @seealso
#' \link[circlize]{circos.dendrogram}
#'
#' @source
#' This code is based on the work of Zuguang Gu. If you use the function, please cite both
#' dendextend (see: \code{citation("dendextend")}), as well as the circlize package (see: \code{citation("circlize")}).
#'
#' @return
#' The dend that was used for plotting.
#'
#' @examples
#'
#' \dontrun{
#'
#' dend <- iris[1:40, -5] %>%
#'   dist() %>%
#'   hclust() %>%
#'   as.dendrogram() %>%
#'   set("branches_k_color", k = 3) %>%
#'   set("branches_lwd", c(5, 2, 1.5)) %>%
#'   set("branches_lty", c(1, 1, 3, 1, 1, 2)) %>%
#'   set("labels_colors") %>%
#'   set("labels_cex", c(.9, 1.2)) %>%
#'   set("nodes_pch", 19) %>%
#'   set("nodes_col", c("orange", "black", "plum", NA))
#'
#' circlize_dendrogram(dend)
#' circlize_dendrogram(dend, labels = FALSE)
#' circlize_dendrogram(dend, facing = "inside", labels = FALSE)
#'
#'
#' # In the following we get the dendrogram but can also get extra information on top of it
#' circos.initialize("foo", xlim = c(0, 40))
#' circos.track(ylim = c(0, 1), panel.fun = function(x, y) {
#'   circos.rect(1:40 - 0.8, rep(0, 40), 1:40 - 0.2, runif(40), col = rand_color(40), border = NA)
#' }, bg.border = NA)
#' circos.track(ylim = c(0, 1), panel.fun = function(x, y) {
#'   circos.text(1:40 - 0.5, rep(0, 40), labels(dend),
#'     col = labels_colors(dend),
#'     facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5)
#'   )
#' }, bg.border = NA, track.height = 0.1)
#' max_height <- attr(dend, "height")
#' circos.track(ylim = c(0, max_height), panel.fun = function(x, y) {
#'   circos.dendrogram(dend, max_height = max_height)
#' }, track.height = 0.5, bg.border = NA)
#' circos.clear()
#' }
circlize_dendrogram <- function(dend, facing = c("outside", "inside"), labels = TRUE,
                                labels_track_height = 0.1,
                                dend_track_height = 0.5,
                                ...) {
  if (!requireNamespace("circlize")) {
    stop("The 'circlize' package is not installed on your system.\nYou first need to run:\n install.packages('circlize') \nbefore you can use the circlize_dendrogram function.")
  }

  n_labaels <- nleaves(dend)
  dend_labels_colors <- labels_colors(dend)
  dend_labels_cex <- labels_cex(dend)
  labels_dend <- labels(dend)
  if (as.logical(anyDuplicated(labels_dend))) {
    warning("Not all labels are unique. Therefore, we pad the labels with a running number, so to be able to produce the plot.")
    labels(dend) <- paste0(seq_along(labels_dend), "_", labels_dend)
    labels_dend <- labels(dend)
  }



  if (is.null(dend_labels_cex)) dend_labels_cex <- rep(1, n_labaels)

  circlize::circos.initialize("dendrogram", xlim = c(0, n_labaels))

  if (is.null(labels_track_height) | is.na(labels_track_height)) labels_track_height <- max(strwidth(labels_dend))


  # plot labels
  if (labels) {
    circlize::circos.track(ylim = c(0, 1), panel.fun = function(x, y) {
      circlize::circos.text(
        x = 1:n_labaels - 0.5,
        y = rep(0, n_labaels),
        labels = labels_dend,
        cex = dend_labels_cex,
        col = dend_labels_colors,
        facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5)
      )
    }, bg.border = NA, track.height = labels_track_height)
  }

  # plot tree
  max_height <- attr(dend, "height")
  circlize::circos.track(ylim = c(0, max_height), panel.fun = function(x, y) {
    circlize::circos.dendrogram(dend, facing = facing, max_height = max_height)
  }, track.height = dend_track_height, bg.border = NA)


  circlize::circos.clear()

  invisible(dend)
}

# labels_cex(dend) <- 3
# plot(dend)
# circlize_dendrogram(dend, labels_ylim = c(0,100))
#


#
# library(dendextend)
#
#  circlize_dendrogram(dend)
#
#

Try the dendextend package in your browser

Any scripts or data that you put into this service are public.

dendextend documentation built on March 31, 2023, 10:17 p.m.