diff --git a/.Rbuildignore b/.Rbuildignore index 44f6654..ceeeff9 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -9,3 +9,5 @@ paper.md paper.bib ^joss$ +^doc$ +^Meta$ diff --git a/.gitignore b/.gitignore index 6c31561..44d2d95 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ .httr-oauth .DS_Store inst/doc -.Rprofile \ No newline at end of file +.Rprofile +/doc/ +/Meta/ diff --git a/DESCRIPTION b/DESCRIPTION index a064bbd..06d56cb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -16,6 +16,7 @@ Imports: forcats, ggplot2, ggplotify, + ggprism, ggpubr, ggrepel, grid, @@ -30,7 +31,7 @@ Imports: umap Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 Suggests: knitr, rmarkdown, diff --git a/R/PAVER_hunter_plot.R b/R/PAVER_hunter_plot.R index 4ca3609..fa45189 100644 --- a/R/PAVER_hunter_plot.R +++ b/R/PAVER_hunter_plot.R @@ -5,6 +5,7 @@ #' #' @param PAVER_result a list containing the output of PAVER analysis #' @param unit optionally, the unit of enrichment analysis for the figure legend title. +#' @param show_row_titles a logical indicating whether to show row titles in the heatmap. #' #' @return A heatmap of the expression data with clustering and color-coded values based on the direction of regulation. #' @@ -12,71 +13,112 @@ #' TRUE #' #' @export -PAVER_hunter_plot <- function(PAVER_result, unit=NULL) { +PAVER_hunter_plot <- function(PAVER_result, unit=NULL, show_row_titles=TRUE) { data = PAVER_result$prepared_data %>% - tidyr::pivot_wider(names_from = "Group", values_from = c("value"), id_cols = "GOID") %>% + tidyr::pivot_wider( + names_from = "Group", + values_from = c("value"), + id_cols = "GOID" + ) %>% dplyr::inner_join(PAVER_result$clustering %>% - dplyr::select(.data$GOID, .data$Cluster), by = "GOID") %>% + dplyr::select(.data$GOID, .data$Cluster), + by = "GOID") %>% dplyr::mutate(Cluster = forcats::fct_drop(.data$Cluster)) %>% dplyr::mutate(dplyr::across( .cols = dplyr::where(is.numeric), - .fns = ~ tidyr::replace_na(.x, 0))) %>% + .fns = ~ tidyr::replace_na(.x, 0) + )) %>% dplyr::distinct(.data$GOID, .keep_all = TRUE) mat = data %>% dplyr::select(dplyr::where(is.numeric)) %>% as.matrix() - min = min(mat, na.rm=T) - max = max(mat, na.rm=T) + min = min(mat, na.rm = T) + max = max(mat, na.rm = T) - if(nlevels(PAVER_result$prepared_data$Direction) != 1) { #If the data is signed, 0 is the middle + if (nlevels(PAVER_result$prepared_data$Direction) != 1) { + #If the data is signed, 0 is the middle col_fun = circlize::colorRamp2(c(min, 0, max), c("blue", "white", "red")) at = c(min, 0, max) labels = c(round(min, 2), 0, round(max, 2)) } else { at = c(min, max) labels = c(round(min, 2), round(max, 2)) - if(levels(PAVER_result$prepared_data$Direction) == "+") { + if (levels(PAVER_result$prepared_data$Direction) == "+") { col_fun = circlize::colorRamp2(c(min, max), c("white", "red")) } else { col_fun = circlize::colorRamp2(c(min, max), c("white", "blue")) } } - lgd = ComplexHeatmap::Legend(col_fun = col_fun, - title = unit, - at = at, - labels = labels, - direction = "horizontal", - title_position = "lefttop", - title_gp = grid::gpar(fontsize = 9,fontface="bold"), - labels_gp = grid::gpar(fontsize = 9,fontface="bold")) - - if(ncol(mat) >= 2) { - dend = ComplexHeatmap::cluster_within_group(mat %>% t(), data$Cluster) + lgd = ComplexHeatmap::Legend( + col_fun = col_fun, + title = unit, + at = at, + labels = labels, + direction = "horizontal", + title_position = "lefttop", + title_gp = grid::gpar(fontsize = 8, fontface = + "bold"), + labels_gp = grid::gpar(fontsize = 8, fontface = + "bold"), + legend_width = grid::unit(1, "cm"), + ) + + c_data = mat %>% t() + + #If there is only one column, we need to duplicate the data to get the clustering + if (ncol(mat) >= 1) { + c_data = rbind(c_data, c_data) } - ht = ComplexHeatmap::Heatmap(mat, - col = col_fun, - row_title_gp = grid::gpar(fontsize = 9,fontface="bold"), - column_names_gp = grid::gpar(fontsize = 9,fontface="bold"), - column_names_rot = 0, - column_names_centered = TRUE, - row_title_rot = 0, - row_title_side = "right", - row_gap = grid::unit(1, "mm"), - show_row_dend = T, - cluster_rows = if (ncol(mat) >= 2) dend else T, - cluster_columns = ncol(mat) >= 3, - split = if (ncol(mat) >= 2) nlevels(data$Cluster) else data$Cluster, - show_heatmap_legend = FALSE, - border = TRUE) - - ht_draw = ComplexHeatmap::draw(ht, - heatmap_legend_list = lgd, - heatmap_legend_side="bottom") + dend = ComplexHeatmap::cluster_within_group(c_data, data$Cluster) + + color_order = data[stats::order.dendrogram(dend),]$Cluster %>% forcats::fct_inorder() %>% levels() + + plot_colors = PAVER_result$colors %>% + magrittr::set_names(levels(data$Cluster)) + + plot_colors = plot_colors[color_order] + + cluster_annotation = ComplexHeatmap::rowAnnotation(Cluster = ComplexHeatmap::anno_block(gp = grid::gpar(fill = plot_colors)), + width = grid::unit(.25, "cm")) + + args = list( + matrix = mat, + col = col_fun, + left_annotation = cluster_annotation, + row_title_gp = grid::gpar(fontsize = 8, fontface = "bold"), + column_names_gp = grid::gpar(fontsize = 8, fontface = "bold"), + column_names_rot = 0, + column_names_centered = TRUE, + row_title_rot = 0, + row_title_side = "right", + row_gap = grid::unit(1, "mm"), + show_row_dend = FALSE, + show_column_dend = FALSE, + cluster_rows = dend, + cluster_columns = ncol(mat) >= 3, + split = nlevels(data$Cluster), + show_heatmap_legend = FALSE, + border = TRUE, + row_title = NULL + ) + + if (show_row_titles) { + args$row_title = character() + } + + ht = do.call(ComplexHeatmap::Heatmap, args) + + ht_draw = ComplexHeatmap::draw( + ht, + heatmap_legend_list = lgd, + heatmap_legend_side = "bottom", + padding = grid::unit(c(1, 1, 1, 1), "mm") + ) plot = grid::grid.grabExpr(ComplexHeatmap::draw(ht_draw)) %>% ggplotify::as.ggplot() diff --git a/R/PAVER_theme_plot.R b/R/PAVER_theme_plot.R index 14c0232..5b2c254 100644 --- a/R/PAVER_theme_plot.R +++ b/R/PAVER_theme_plot.R @@ -4,6 +4,7 @@ #' of the UMAP layout colored by cluster assignments. #' #' @param PAVER_result a list containing the output of PAVER analysis +#' @param show_cluster_legend a logical indicating whether to show the cluster legend. #' #' @return A ggplot2 scatterplot of the UMAP layout colored by cluster assignments #' @@ -11,7 +12,7 @@ #' TRUE #' #' @export -PAVER_theme_plot <- function(PAVER_result) { +PAVER_theme_plot <- function(PAVER_result, show_cluster_legend=TRUE) { plot = PAVER_result$umap$layout %>% tibble::as_tibble(rownames = NA, .name_repair = "universal_quiet") %>% @@ -24,7 +25,40 @@ PAVER_theme_plot <- function(PAVER_result) { colour = .data$Cluster)) + ggplot2::geom_point(ggplot2::aes(shape = .data$Group)) + ggplot2::scale_color_manual(values = PAVER_result$colors) + - ggpubr::theme_pubr(legend = "right") + ggprism::theme_prism(base_size = 9) + + ggplot2::theme( + axis.title.y = ggplot2::element_text(margin = ggplot2::margin(t = 0, r = 0, b = 0, l = 0)), + axis.title.x = ggplot2::element_text(margin = ggplot2::margin(t = 0, r = 0, b = 0, l = 0)), + axis.text.x = ggplot2::element_blank(), + axis.text.y = ggplot2::element_blank(), + axis.ticks.x = ggplot2::element_blank(), + axis.ticks.y = ggplot2::element_blank(), + legend.position = "bottom", + legend.direction = "horizontal", + legend.spacing.y = grid::unit(-1, 'mm'), + legend.spacing.x = grid::unit(-1, 'mm'), + legend.box.spacing = grid::unit(-1, 'mm'), + legend.key.spacing.x = grid::unit(-1, "mm"), + legend.key.spacing.y = grid::unit(-1, "mm"), + legend.box.margin = ggplot2::margin(), + legend.box = "vertical", + panel.grid = ggplot2::element_blank(), + panel.border = ggplot2::element_blank(), + plot.margin = grid::unit(c(0, 0, 0, 0), "mm"), + panel.spacing = grid::unit(c(0, 0, 0, 0), "mm"), + legend.margin = ggplot2::margin(0), + legend.text = ggplot2::element_text(face = "bold", size = 9, margin = ggplot2::margin(t = 0, r = 0, b = 0, l = 0)) + ) + + ggplot2::guides( + fill = ggplot2::guide_legend(byrow = T, + override.aes = list(size = 2.5)), + shape = ggplot2::guide_legend(byrow = T, + override.aes = list(size = 2.5))) + + {if (show_cluster_legend) ggplot2::guides(color = ggplot2::guide_legend( + byrow = TRUE, + ncol = 1, + override.aes = list(shape = 15, size = 2.75) + )) else ggplot2::guides(color = "none")} plot } diff --git a/man/PAVER_hunter_plot.Rd b/man/PAVER_hunter_plot.Rd index 00b4e74..9ec7ca6 100644 --- a/man/PAVER_hunter_plot.Rd +++ b/man/PAVER_hunter_plot.Rd @@ -4,12 +4,14 @@ \alias{PAVER_hunter_plot} \title{PAVER_hunter_plot} \usage{ -PAVER_hunter_plot(PAVER_result, unit = NULL) +PAVER_hunter_plot(PAVER_result, unit = NULL, show_row_titles = TRUE) } \arguments{ \item{PAVER_result}{a list containing the output of PAVER analysis} \item{unit}{optionally, the unit of enrichment analysis for the figure legend title.} + +\item{show_row_titles}{a logical indicating whether to show row titles in the heatmap.} } \value{ A heatmap of the expression data with clustering and color-coded values based on the direction of regulation. diff --git a/man/PAVER_theme_plot.Rd b/man/PAVER_theme_plot.Rd index f6b8cf6..2781bb5 100644 --- a/man/PAVER_theme_plot.Rd +++ b/man/PAVER_theme_plot.Rd @@ -4,10 +4,12 @@ \alias{PAVER_theme_plot} \title{PAVER_theme_plot} \usage{ -PAVER_theme_plot(PAVER_result) +PAVER_theme_plot(PAVER_result, show_cluster_legend = TRUE) } \arguments{ \item{PAVER_result}{a list containing the output of PAVER analysis} + +\item{show_cluster_legend}{a logical indicating whether to show the cluster legend.} } \value{ A ggplot2 scatterplot of the UMAP layout colored by cluster assignments diff --git a/renv.lock b/renv.lock index 32e24aa..08dcbe8 100644 --- a/renv.lock +++ b/renv.lock @@ -1010,6 +1010,26 @@ ], "Hash": "1547863db3b472cf7181973acf649f1a" }, + "ggprism": { + "Package": "ggprism", + "Version": "1.0.5", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "digest", + "ggplot2", + "glue", + "grid", + "gtable", + "rlang", + "scales", + "stats", + "tibble", + "utils" + ], + "Hash": "6b1020c155c1048c18f39df11eb464e8" + }, "ggpubr": { "Package": "ggpubr", "Version": "0.6.0", diff --git a/vignettes/PAVER.Rmd b/vignettes/PAVER.Rmd index 5b12240..54b5b96 100644 --- a/vignettes/PAVER.Rmd +++ b/vignettes/PAVER.Rmd @@ -42,7 +42,7 @@ PAVER_result = prepare_data(input, embeddings, term2name) After preparing your data, PAVER can generate a set of pathway clusters and identify the most representative pathway (theme) for each cluster. The following code chunk demonstrates how to generate pathway clusters using the example data provided in the PAVER package. To constrain the pathway clustering, we pass the following arguments to (dynamicTreeCut)[https://cran.r-project.org/package=dynamicTreeCut]. Increasing `minClusterSize` will result in fewer clusters, while increasing `maxCoreScatter` will result in more clusters. ```{r} -minClusterSize = 5 +minClusterSize = 3 maxCoreScatter = 0.33 minGap = (1 - maxCoreScatter) * 3 / 4 PAVER_result = generate_themes(