In this bit of code, I am trying to control the color scale on the legend and also plot. I want zero to allows be white, negative various shades of blue, positive various red. the distrubtion of the data is a bit different, where one plot might have a min -1 max 4, while another one might be -4 to 8. Any ideas to control this? Currently the color scale drifts a bit. In one plot 0 might be red, another it might be blue. I think this has to do with the distribution of each plot.
# Open a single PDF device
pdf(file = "PathwayHeatmap_clustered_by_pathway1.pdf", width = 12, height = 10)
# Loop through pathways and generate heatmaps
for (pathway in unique(combined_heatmap_data$pathway)) {
# Subset the data for the current pathway
pathway_data <- combined_heatmap_data[combined_heatmap_data$pathway == pathway, ]
# Reshape the data for heatmap (Z-scores across comparisons)
pathway_zscore_matrix <- dcast(pathway_data, gene ~ comparison, value.var = "Zscore", fun.aggregate = mean)
rownames(pathway_zscore_matrix) <- pathway_zscore_matrix$gene
pathway_zscore_matrix <- as.matrix(pathway_zscore_matrix[, -1]) # Remove the gene column
# Perform hierarchical clustering
gene_cluster <- hclust(dist(pathway_zscore_matrix), method = "ward.D")
pathway_zscore_matrix <- pathway_zscore_matrix[gene_cluster$order, ] # Reorder matrix by gene clustering
# Create a heatmap for the current pathway
heatmap_obj <- Heatmap(
pathway_zscore_matrix,
name = "Zscore",
col = colorRampPalette(c("blue", "white", "red"))(100),
show_row_names = TRUE,
show_column_names = TRUE,
row_dend_side = "left",
column_dend_side = "top",
cluster_rows = TRUE,
cluster_columns = FALSE, # Keep columns fixed (i.e., comparisons)
row_title = pathway,
row_title_gp = gpar(fontface = "bold"), # Make pathway name bold
heatmap_legend_param = list(
title = "Zscore",
at = seq(-4, 8, by = 2), # Set legend range from -4 to 8
labels = seq(-4, 8, by = 2),
legend_side = "right" # Move legend to the right
),
top_annotation = NULL, # Remove comparison annotation
column_names_gp = gpar(fontface = "bold"), # Make x-axis labels bold
column_names_rot = 0 # Set x-axis labels to horizontal (0 degrees)
)
# Draw the heatmap within the same PDF page
draw(heatmap_obj)
}
# Close the PDF device (all heatmaps are now in a single PDF)
dev.off()
Check out the help page. For the col
argument it calls for a vector of colors (you did this) if the mapping is discrete or a color mapping function if continuous (you want this).
It links to the help book and suggests circlize::colorRamp2()
. You provide a vector of positions and then a same length vector of colors which will map to those positions and the function will interpolate between those, so you set white at zero. You can play around with where you want these positions to be.
You also go through the trouble of clustering and then reordering your matrix beforehand, but the heatmap function ignores the matrix row order when you specify cluster_rows = TRUE
and it will instead use some default method to cluster and order. The book shows there are many ways to customize the clustering method, but the easiest in your case is the clustering_method_rows
argument which the book mentions will take any of the methods available to the stats::hclust()
function.
library(ComplexHeatmap)
set.seed(123)
mat1 <- matrix(rnorm(n = 500, mean = -1, sd = 1), nrow = 50)
colnames(mat1) <- LETTERS[1:10]
row.names(mat1) <- c(letters[1:25], paste0(letters[1:25], rev(letters[1:25])))
heatmap_obj <- Heatmap(
mat1,
col = circlize::colorRamp2(c(-4, 0, 8), c("blue", "white", "red")),
show_row_names = TRUE,
show_column_names = TRUE,
row_dend_side = "left",
column_dend_side = "top",
cluster_rows = TRUE,
clustering_method_rows = "ward.D",
cluster_columns = FALSE,
row_title = "mat1",
row_title_gp = gpar(fontface = "bold"),
heatmap_legend_param = list(
title = "Zscore",
at = seq(-4, 8, by = 2),
labels = seq(-4, 8, by = 2),
legend_side = "right"
),
top_annotation = NULL,
column_names_gp = gpar(fontface = "bold"),
column_names_rot = 0
)
draw(heatmap_obj)