Skip to content

Commit

Permalink
Merge pull request #145 from uclahs-cds/hwinata-make-prettier-hm
Browse files Browse the repository at this point in the history
Aesthetic changes to heatmap and clone genome distribution plot
  • Loading branch information
whelena authored Oct 23, 2024
2 parents 46cc7f3 + 26b02b4 commit dc3329c
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 59 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Documentation for heatmaps and clone-genome distribution plot
* Option to disable node drawing with node-by-node control
* Node-by-node control of node size
* Aesthetic changes for heatmap and clone-genome distribution plot
* Add parameters to specify polygon shape and width.

## Update
Expand Down
5 changes: 0 additions & 5 deletions R/create.ccf.heatmap.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
create.ccf.heatmap <- function(
x,
ccf.thres = NULL,
cluster.dimensions = 'both',
clustering.method = 'complete',
distance.method = 'euclidean',
Expand All @@ -11,10 +10,6 @@ create.ccf.heatmap <- function(
...
) {

if (!is.null(ccf.thres)) {
x[x <= ccf.thres] <- 0;
}

col.labels <- seq(min(x), max(x), length.out = 5);

return(BoutrosLab.plotting.general::create.heatmap(
Expand Down
99 changes: 77 additions & 22 deletions R/create.ccf.summary.heatmap.R
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
create.ccf.summary.heatmap <- function(
DF,
ccf.thres = NULL,
ccf.limits = NULL,
median.col = 'median.ccf.per.sample',
clone.order = NULL,
sample.order = NULL,
hm.col.scheme = c('white', 'blue'),
clone.colours = NULL,
subplot.xlab.cex = 1.2,
subplot.xaxis.cex = 1,
subplot.xaxis.fontface = 'bold',
Expand All @@ -16,6 +17,9 @@ create.ccf.summary.heatmap <- function(
legend.size = 3,
legend.title.cex = 1.2,
legend.label.cex = 1,
legend.x = 0.9,
legend.y = 0.8,
plot.objects.heights = c(0.3, 1),
...
) {

Expand All @@ -25,20 +29,33 @@ create.ccf.summary.heatmap <- function(
x.axis = 'clone.id'
);

if (!is.null(ccf.thres)) {
arr[arr <= ccf.thres] <- 0;
if (!is.null(ccf.limits)) {
if (length(ccf.limits) != 2) {
stop('ccf.limits must be a vector of length 2');
}
arr[arr < ccf.limits[1]] <- ccf.limits[1];
arr[arr > ccf.limits[2]] <- ccf.limits[2];
}

clone.df <- aggregate(CCF ~ clone.id, data = DF[DF$CCF > 0, ], FUN = length);
sample.df <- aggregate(CCF ~ ID, data = DF[DF$CCF > 0, ], FUN = length);
clone.df <- aggregate(
SNV.id ~ clone.id,
data = DF[DF$CCF > 0, ],
FUN = function(x) length(unique(x))
);
sample.df <- aggregate(SNV.id ~ ID, data = DF[DF$CCF > 0, ], FUN = length);
names(sample.df)[2] <- names(clone.df)[2] <- 'nsnv';

if (!is.null(clone.order) & !is.null(sample.order)) {
arr <- arr[clone.order, sample.order];
arr <- arr[clone.order, rev(sample.order)];
clone.df$clone.id <- factor(clone.df$clone.id, levels = clone.order);
sample.df$ID <- factor(sample.df$ID, levels = sample.order);
sample.df$ID <- factor(sample.df$ID, levels = rev(sample.order));
}

clone.yaxis <- auto.axis(
x = clone.df$nsnv,
log.scaled = FALSE,
num.labels = 3
);
clone.bar <- BoutrosLab.plotting.general::create.barplot(
formula = nsnv ~ clone.id,
data = clone.df,
Expand All @@ -49,30 +66,38 @@ create.ccf.summary.heatmap <- function(
ylab.cex = subplot.ylab.cex,
yaxis.cex = subplot.yaxis.cex,
yaxis.fontface = subplot.yaxis.fontface,
ylimits = c( - max(clone.df$nsnv) * 0.05, max(clone.df$nsnv) * 1.05)
ylimits = c( - 0.05, 1.05) * max(clone.yaxis$at),
yat = clone.yaxis$at
);

# restrict number of ticks in the SNV per sample barplot
sample.xaxis <- auto.axis(
x = sample.df$nsnv,
log.scaled = FALSE,
num.labels = 3
);
sample.bar <- BoutrosLab.plotting.general::create.barplot(
formula = ID ~ nsnv,
data = sample.df,
xlab.label = 'SNV per sample',
xlab.label = 'SNV\nper sample',
xlab.cex = subplot.xlab.cex,
xaxis.cex = subplot.xaxis.cex,
xaxis.fontface = subplot.xaxis.fontface,
xlimits = c( - max(sample.df$nsnv) * 0.05, max(sample.df$nsnv) * 1.05),
xlimits = c( - 0.05, 1.05) * max(sample.xaxis$at),
yaxis.cex = 0,
yaxis.tck = 0,
ylab.label = NULL,
plot.horizontal = TRUE
plot.horizontal = TRUE,
xat = sample.xaxis$at
);

hm <- BoutrosLab.plotting.general::create.heatmap(
x = arr,
cluster.dimensions = 'none',
xlab.label = 'Clone ID',
xlab.cex = subplot.xlab.cex,
xlab.cex = ifelse(is.null(clone.colours), subplot.xlab.cex, 0),
xaxis.lab = rownames(arr),
xaxis.cex = subplot.xaxis.cex,
xaxis.cex = ifelse(is.null(clone.colours), subplot.xaxis.cex, 0),
xaxis.fontface = subplot.xaxis.fontface,
xaxis.rot = hm.xaxis.rot,
ylab.label = 'Sample ID',
Expand All @@ -88,27 +113,57 @@ create.ccf.summary.heatmap <- function(
list(
legend = list(
title = 'CCF',
labels = c(min(arr), max(arr)),
labels = c(min(arr), rep('', legend.size), max(arr)),
colours = c('white', 'blue'),
border = 'black',
continuous = TRUE
continuous = TRUE,
cex = legend.label.cex
)
),
size = legend.size,
title.cex = legend.title.cex,
label.cex = legend.label.cex
);

if (!is.null(clone.colours)) {
clone.cov <- BoutrosLab.plotting.general::create.heatmap(
x = t(clone.colours[rownames(arr)]),
xlab.label = 'Clone ID',
xlab.cex = subplot.xlab.cex,
xaxis.lab = rownames(arr),
xaxis.cex = subplot.xaxis.cex,
xaxis.fontface = subplot.xaxis.fontface,
xaxis.rot = hm.xaxis.rot,
input.colours = TRUE,
clustering.method = 'none',
grid.col = FALSE,
print.colour.key = FALSE,
yaxis.tck = 0
);
plot.list <- list(clone.bar, hm, sample.bar, clone.cov);
layout.skip <- c(FALSE, TRUE, FALSE, FALSE, FALSE, TRUE);
layout.height <- 3;
if (length(plot.object.heights) == 2 ) {
plot.objects.heights <- c(plot.object.heights, 0.2);
}
} else {
plot.list <- list(clone.bar, hm,sample.bar);
layout.skip <- c(FALSE, TRUE, FALSE, FALSE);
layout.height <- 2;
}

return(BoutrosLab.plotting.general::create.multipanelplot(
plot.objects = list(clone.bar, hm, sample.bar),
plot.objects = plot.list,
layout.width = 2,
layout.height = 2,
plot.objects.heights = c(0.3, 1),
layout.height = layout.height,
plot.objects.heights = plot.objects.heights,
plot.objects.widths = c(1, 0.2),
layout.skip = c(FALSE, TRUE, FALSE, FALSE),
legend = list(right = list(
fun = legend.ccf
)),
layout.skip = layout.skip ,
legend = list(inside = list(
fun = legend.ccf,
x = legend.x,
y = legend.y
)),
...
));
}
9 changes: 7 additions & 2 deletions R/create.clone.genome.distribution.densityplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ create.clone.genome.distribution.densityplot <- function(
data = density.df,
groups = density.df$clone.id,
xlab.label = 'Chromosome',
ylab.label = 'Number of SNVs',
ylab.label = 'SNV Density',
xlimits = c(0, sum(chr.info$length)),
xaxis.lab = chr.info$chr,
xat = chr.info$xat,
Expand All @@ -26,7 +26,12 @@ create.clone.genome.distribution.densityplot <- function(
}

calculate.density.and.scale <- function(cluster.df) {
density <- density(x = cluster.df$genome.pos, bw = 'nrd', adjust = 0.05, na.rm = TRUE);
# 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;
Expand Down
35 changes: 23 additions & 12 deletions R/create.clone.genome.distribution.plot.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ create.clone.genome.distribution.plot <- function(
clone.colours = NULL,
filename = NULL,
multi.sample = FALSE,
alpha = 0.25,
legend.x = 0.1,
legend.y = 0.55,
...
) {

Expand All @@ -16,21 +19,17 @@ create.clone.genome.distribution.plot <- function(
clone.order <- sort(unique(snv.df$clone.id));
}

if (!is.null(filename)) {
save.plt <- filename;
}

if (multi.sample) {
# if multi-sample is true, check for sample ids in 'ID' column
if (is.null(snv.df$ID)) {
stop('ID column must contain sample ID if multi.sample is TRUE');
}
# filename must be a directory
if (!dir.exists(save.plt)) {
if (!dir.exists(filename)) {
stop('filename must be a directory if multi.sample is TRUE');
}
} else {
if (dir.exists(save.plt)) {
if (dir.exists(filename)) {
stop('filename must be a path (not a directory) if multi.sample is FALSE');
}
snv.df$ID <- 'all';
Expand All @@ -51,16 +50,22 @@ create.clone.genome.distribution.plot <- function(
# Iterate through each sample -------------------------------------------------------------
print(paste('Plotting clone distribution across the genome for sample:', s));

sample.df <- droplevels(snv.df[snv.df$ID == s, ])
sample.df <- droplevels(snv.df[snv.df$ID == s, ]);
sample.df <- unique(sample.df[, c('clone.id', 'genome.pos', 'SNV.id', 'ID')]);
if (multi.sample & !is.null(filename)) {
save.plt <- file.path(save.plt, paste0(s, '.png'));
save.plt <- file.path(filename, paste0(s, '.png'));
} else {
save.plt <- filename;
}

plt <- create.clone.genome.distribution.plot.per.sample(
sample.df,
clone.colours[levels(sample.df$clone.id)],
chr.info,
save.plt = ifelse(is.null(filename), NULL, save.plt),
alpha = alpha,
legend.x = legend.x,
legend.y = legend.y,
...
);
}
Expand All @@ -84,6 +89,9 @@ create.clone.genome.distribution.plot.per.sample <- function(
legend.size = 3,
legend.title.cex = 1.2,
legend.label.cex = 1,
legend.x = 0.1,
legend.y = 0.55,
alpha = 0.25,
...
) {

Expand All @@ -105,7 +113,7 @@ create.clone.genome.distribution.plot.per.sample <- function(
cluster.legend <- BoutrosLab.plotting.general::legend.grob(
list(
legend = list(
title = 'Clones',
title = 'Clone ID',
labels = names(clone.colours),
colours = c(clone.colours),
border = 'black'
Expand All @@ -130,7 +138,8 @@ create.clone.genome.distribution.plot.per.sample <- function(
xlab.cex = 0,
ylab.cex = ylab.cex,
xaxis.cex = 0,
yaxis.cex = yaxis.cex
yaxis.cex = yaxis.cex,
alpha = alpha
);

density.plt <- create.clone.genome.distribution.densityplot(
Expand Down Expand Up @@ -161,8 +170,10 @@ create.clone.genome.distribution.plot.per.sample <- function(
layout.width = 1,
layout.height = 2,
plot.objects.heights = c(height.scatter, 5) / total.height,
legend = list(right = list(
fun = cluster.legend
legend = list(inside = list(
fun = cluster.legend,
x = legend.x,
y = legend.y
)),
height = total.height,
width = width,
Expand Down
4 changes: 1 addition & 3 deletions R/create.clone.genome.distribution.scatterplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ create.clone.genome.distribution.scatterplot <- function(
nclone,
chr.info,
save.plt = NULL,
alpha = 0.25,
...
) {

scatter.df$clone.id <- factor(scatter.df$clone.id, levels = rev(levels(scatter.df$clone.id)));
return(BoutrosLab.plotting.general::create.scatterplot(
filename = save.plt,
formula = clone.id ~ genome.pos,
Expand All @@ -21,8 +21,6 @@ create.clone.genome.distribution.scatterplot <- function(
yat = seq(1, nclone, 1),
xlimits = c(0, sum(chr.info$length)),
col = scatter.df$colour,
# col.border = rep(NULL, nsnv),
alpha = alpha,
abline.v = chr.info$start,
...
));
Expand Down
Loading

0 comments on commit dc3329c

Please sign in to comment.