Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export(create.ccf.heatmap)
export(create.cluster.heatmap)
export(create.ccf.summary.heatmap)
export(create.clone.genome.distribution.plot)
export(create.ccf.densityplot)

export(data.frame.to.array)
export(update.descendant.property)
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Add option to use scale bars instead of y-axes.
* Wrapper function for `SRCgrob` to automatically save plots to file
* Add option to annotate the CCF summary heatmap with the cell values.
* Function to generate single-sample density plot
* Add support for 1xn and 1x1 heatmaps.
* Add `get.colours.in.order` function to get a list of colours and corresponding clone ID order.
* Add `sample.order` and `clone.order` as input parameters to `create.cluster.heatmap`
Expand All @@ -36,6 +37,7 @@
* Resolved issue where the spread parameter was not applied in dendrogram mode.
* Resolved issue for simple dendrogram trees ( < 6 nodes or binary tree), where node angles were not calculated correctly.


# CancerEvolutionVisualization 2.0.1 (2023-11-17)

## Added
Expand Down
19 changes: 19 additions & 0 deletions R/calculate.density.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
calculate.density <- function(
x,
value = 'genome.pos',
group = 'clone.id',
scale = TRUE,
...
) {

if (nrow(x) <= 1) {
return(NULL);
}
density <- density(x = x[[value]], bw = 'nrd', na.rm = TRUE, ...);
density.df <- as.data.frame(density[c('x', 'y')]);
density.df$clone.id <- unique(x[[group]]);
if (scale) {
density.df$y <- nrow(x) / sum(density.df$y) * density.df$y;
}
return(density.df);
}
111 changes: 111 additions & 0 deletions R/create.ccf.densityplot.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
create.ccf.densityplot <- function(
x,
filename = NULL,
clone.colours = NULL,
breaks = 100,
xlab.label = 'CCF',
ylab.label = 'SNV Density',
xlimits = c(0, 1.5),
xat = seq(0, 1.5, 0.25),
legend.size = 3,
legend.title.cex = 1.2,
legend.label.cex = 1,
legend.x = 0.8,
legend.y = 0.9,
height = 6,
width = 10,
size.units = 'in',
resolution = 1000,
...
) {

if (is.null(clone.colours)) {
clone.colours <- get.colours(x$clone.id, return.names = TRUE);
}

mean.ccf <- aggregate(CCF ~ clone.id, data = x, FUN = mean);
nsnv <- aggregate(SNV.id ~ clone.id, data = x, FUN = length);

density.list <- list();
for (k in unique(x$clone.id)) {
density.list[[k]] <- calculate.density(
x = x[x$clone.id == k, ],
value = 'CCF',
adjust = 1,
scale = FALSE
);
}
density.df <- do.call(rbind, density.list);
density.df$y <- density.df$y * (nsnv$SNV.id[match(density.df$clone.id, nsnv$clone.id)] / nrow(x));

legend.label <- sapply(names(clone.colours), function(k) {
nsnv <- nsnv[nsnv$clone.id == k, ]$SNV.id;
return(paste0(k, ' (', nsnv, ')'));
});
clone.legend <- BoutrosLab.plotting.general::legend.grob(
list(
legend = list(
title = 'Clone (SNVs)',
labels = legend.label[names(clone.colours)],
colours = c(clone.colours),
border = 'black'
)
),
size = legend.size,
title.just = 'left',
title.cex = legend.title.cex,
label.cex = legend.label.cex
);

ymax <- ceiling(max(density.df$y, na.rm = TRUE));

hist <- BoutrosLab.plotting.general::create.histogram(
x = x$CCF,
type = 'density',
col = 'gray90',
border.col = 'gray30',
lwd = 0.1,
xlab.label = xlab.label,
ylab.label = ylab.label,
xlimits = xlimits,
xat = xat,
ylimits = c(-0.05, 1.05) * ymax,
legend = list(inside = list(
fun = clone.legend,
x = legend.x,
y = legend.y
)),
...
);

scatter <- BoutrosLab.plotting.general::create.scatterplot(
formula = y ~ x,
data = density.df,
groups = density.df$clone.id,
type = 'l',
lwd = 3,
col = clone.colours,
xlimits = xlimits,
ylimits = c(-0.05, 1.05) * ymax,
abline.v = mean.ccf$CCF,
abline.lwd = 0.5,
abline.lty = 'longdash',
abline.col = 'gray50',
add.text = TRUE,
text.labels = lapply(mean.ccf$CCF, round, 2),
text.x = mean.ccf$CCF,
text.y = ymax,
text.fontface = 'bold',
text.cex = legend.title.cex
);

combn.plt <- hist + scatter;
return(BoutrosLab.plotting.general::write.plot(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double-checking. Are we returning the results of write.plot in the rest of the package, or just returning the BPG object (so here, returning scatter).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checked with BPG and BPG does return write.plot for all the create. functions.

trellis.object = combn.plt,
filename = filename,
height = height,
width = width,
size.units = size.units,
resolution = resolution
));
}
16 changes: 1 addition & 15 deletions R/create.clone.genome.distribution.densityplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ create.clone.genome.distribution.densityplot <- function(

return(BoutrosLab.plotting.general::create.scatterplot(
filename = save.plt,
formula = count ~ x,
formula = y ~ x,
data = density.df,
groups = density.df$clone.id,
xlab.label = 'Chromosome',
Expand All @@ -24,17 +24,3 @@ create.clone.genome.distribution.densityplot <- function(
...
));
}

calculate.density.and.scale <- function(cluster.df) {
# density should be generated using unque SNV count
density <- density(
x = cluster.df$genome.pos,
bw = 'nrd',
adjust = 0.05, # set to 1E9/3E9 to get density per megabase
na.rm = TRUE);
density.df <- as.data.frame(density[c('x','y')]);
density.df$clone.id <- unique(cluster.df$clone.id);
density.df$count <- nrow(cluster.df) / sum(density.df$y) * density.df$y;

return(density.df)
}
5 changes: 3 additions & 2 deletions R/create.clone.genome.distribution.plot.R
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ create.clone.genome.distribution.plot.per.sample <- function(
warning(paste('Skipping clone', k, 'in sample', unique(sample.df$ID), 'since there is only one SNV'));
next;
}
density.list[[k]] <- calculate.density.and.scale(
cluster.df = sample.df[sample.df$clone.id == k, ]
density.list[[k]] <- calculate.density(
x = sample.df[sample.df$clone.id == k, ],
adjust = 0.05
);
}
density.df <- do.call(rbind, density.list);
Expand Down
3 changes: 2 additions & 1 deletion R/create.cluster.heatmap.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ create.cluster.heatmap <- function(
xaxis.fontface = 'bold',
y.spacing = 1,
colour.scheme = c('white', 'blue'),
plot.objects.heights = c(1, 0.2),
...
) {

Expand Down Expand Up @@ -112,7 +113,7 @@ create.cluster.heatmap <- function(
plot.objects = list(hm, cov),
layout.width = 1,
layout.height = 2,
plot.objects.heights = c(1, 0.2),
plot.objects.heights = plot.objects.heights,
legend = list(right = list(
fun = legend.clone
)),
Expand Down
4 changes: 2 additions & 2 deletions R/create.phylogenetic.tree.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ create.phylogenetic.tree <- function(
tree <- as.data.frame(tree);
if ('node.id' %in% colnames(tree)) {
rownames(tree) <- tree$node.id;
if (!'label' %in% colnames(tree)) {
if (!'label' %in% colnames(tree)) {
tree$label <- tree$node.id;
}
}
}

plt <- SRCGrob(
tree,
Expand Down
51 changes: 51 additions & 0 deletions man/create.ccf.densityplot.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
\name{create.ccf.densityplot}
\alias{create.ccf.densityplot}
\title{CCF Density Plot}
\description{
Creates a density plot of cancer cell fraction (CCF) distribution across a sample.
}
\usage{
create.ccf.densityplot(
x,
filename = NULL,
clone.colours = NULL,
breaks = 100,
xlab.label = 'CCF',
ylab.label = 'SNV Density',
xlimits = c(0, 1.5),
xat = seq(0, 1.5, 0.25),
legend.size = 3,
legend.title.cex = 1.2,
legend.label.cex = 1,
legend.x = 0.8,
legend.y = 0.9,
height = 6,
width = 10,
size.units = 'in',
resolution = 1000,
...
);
}
\arguments{
\item{x}{A data-frame with the following column names: 'SNV.id', 'clone.id', 'CCF'.}
\item{filename}{Filename for tiff output, or if NULL returns the trellis object itself. Defaults to \code{NULL}.}
\item{clone.colours}{Named list to provide a colour scheme for the clone ID covariate bar. If NULL, colours will be randomly generated. Defaults to \code{NULL}.}
\item{breaks}{Number of breaks for the histogram. Defaults to 100.}
\item{xlab.label}{Defaults to \dQuote{CCF}.}
\item{ylab.label}{Defaults to \dQuote{SNV Density}.}
\item{xlimits}{Limits for the x-axis. Defaults to \code{c(0, 1.5)}.}
\item{xat}{Positions for the x-axis labels. Defaults to \code{seq(0, 1.5, 0.25)}.}
\item{legend.size}{Width of the legend boxes in 'character' units. Defaults to 3}
\item{legend.title.cex}{Size of titles in the legends. Defaults to 1.2}
\item{legend.label.cex}{Size of text labels in the legends. Defaults to 1}
\item{legend.x}{x position of the legend. Defaults to 0.8}
\item{legend.y}{y position of the legend. Defaults to 0.9}
\item{height}{Height of the plot. Defaults to 6}
\item{width}{Width of the plot. Defaults to 10}
\item{size.units}{Units for the height and width. Defaults to \dQuote{in}.}
\item{resolution}{Resolution of the plot. Defaults to 1000}
\item{...}{Pass through argument. See BoutrosLab.plotting.general::create.histogram() for further details.}
}
\value{A `grob` object of the heatmap.}
\author{Helena Winata}
\seealso{\code{\link[BoutrosLab.plotting.general]{create.histogram}}, \code{\link[BoutrosLab.plotting.general]{create.scatterplot}}}
2 changes: 2 additions & 0 deletions man/create.cluster.heatmap.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ create.cluster.heatmap(
xaxis.fontface = 'bold',
y.spacing = 1,
colour.scheme = c('white', 'blue'),
plot.objects.heights = c(1, 0.2),
...
);
}
Expand All @@ -46,6 +47,7 @@ create.cluster.heatmap(
\item{xaxis.fontface}{Defaults to \dQuote{bold}.}
\item{y.spacing}{Spacing between heatmap and clone covariate bar. Defaults to 1}
\item{colour.scheme}{Colour scheme for the heatmap. Defaults to \code{c('white', 'blue')}.}
\item{plot.objects.heights}{Object heights. Defaults to \code{c(1, 0.2)}.}
\item{...}{Pass through argument. See BoutrosLab.plotting.general::create.heatmap() for further details.}
}
\value{A `grob` object of the heatmap.}
Expand Down