Exercise 6
Integrating ATAC and RNA sequencing data
Learning Objectives
By the end of this exercise, you will be able to:
- Understand the biological significance of different assays such as ATAC-seq, ChIP-seq for histone marks, DNA methylation, and RNA-seq, and how they relate to gene regulation.
- Process and integrate multi-omics data using SummarizedExperiment objects and annotation data.
- Identify and classify regulatory genomic regions (e.g., gained/lost enhancers, activated/repressed promoters) based on changes in chromatin accessibility, histone modifications, and gene expression.
- Visualize complex multi-omics data by generating heatmaps with the EnrichedHeatmap and ComplexHeatmap R packages, highlighting changes across developmental stages.
- Interpret integrated heatmaps to explore relationships between chromatin state, DNA methylation, and transcriptional output.
- Use custom functions to automate visualization workflows, adapting color scales and annotations for effective data presentation.
Load Libraries
Assay | What It Measures | **Biological Insight* |
---|---|---|
ATAC-seq | Chromatin accessibility | Identifies open chromatin regions, such as promoters and enhancers. |
ChIP-seq (H3K4me3) | Active promoter mark | Marks active promoters; often found at TSS (Transcription Start Sites). |
ChIP-seq (H3K27ac) | Active enhancer/promoter | Marks active regulatory regions, especially enhancers. |
ChIP-seq (H3K4me1) | Primed or poised enhancers | Marks enhancers that may be active or poised, not promoters. |
ChIP-seq (H3K27me3) | Repressive regions | Marks silenced genes or developmental repression (Polycomb repression). |
DNAme | DNA methylation (CpG sites) | Typically associated with gene silencing and heterochromatin. |
RNA-seq | Gene expression | Final transcriptional output; mRNA abundance. |
Load required objects from previous exercises
Here we load the SummarizedExperiment
for the ChIP-seq data
atac <- readRDS("data/atac_se.rds")
h3k4me3 <- readRDS("data/h3k4me3_se.rds")
h3k4me1 <- readRDS("data/h3k4me1_se.rds")
h3k27me3 <- readRDS("data/h3k27me3_se.rds")
h3k27ac <- readRDS("data/h3k27ac_se.rds")
rna <- readRDS("data/rna_se.rds")
rownames(colData(rna)) <- gsub(pattern = "\\.tsv.gz", replacement = "", x = rownames(colData(rna)))
overlap <- readRDS("output/overlap_anno.rds")
mat_ATAC <- readRDS("output/mat_atac.rds")
mat_RNA <- readRDS("output/mat_rna.rds")
mat_H3K4me3 <- readRDS("output/mat_h3k4me3.rds")
mat_H3K4me1 <- readRDS("output/mat_h3k4me1.rds")
mat_H3K27me3 <- readRDS("output/mat_h3k27me3.rds")
mat_H3K27ac <- readRDS("output/mat_h3k27ac.rds")
mat_BS <- readRDS("output/mat_bs.rds")
Regulatory regions
We will sub-categorized the regions from the Exercise 5
based on the above table.
Gained Enhancers (E15.5 > E11.5)
logFC_cols <- grep(pattern = "logFC", x = colnames(elementMetadata(overlap)))
mcols(overlap)[, logFC_cols] <- lapply(mcols(overlap)[, logFC_cols, drop = FALSE], function(x) {
x[is.na(x)] <- 0
return(x)
})
gained_enhancers <- overlap$ATAC_logFC > 0 &
overlap$H3K4me1_logFC > 0 &
overlap$H3K27ac_logFC > 0 &
is.na(overlap$H3K4me3_annotation) &
overlap$ATAC_distanceToTSS > 2500 &
overlap$RNA_logFC > 0
overlap$ATAC_RNA[gained_enhancers] <- "Gained Enhancers"
Lost Enhancers (E15.5 < E11.5)
lost_enhancers <- overlap$ATAC_logFC < 0 &
overlap$H3K4me1_logFC < 0 &
overlap$H3K27ac_logFC < 0 &
is.na(overlap$H3K4me3_annotation) &
overlap$ATAC_distanceToTSS > 2500 &
overlap$RNA_logFC < 0
overlap$ATAC_RNA[lost_enhancers] <- "Lost Enhancers"
Activated Promoters (E15.5 > E11.5)
active_promoters <- overlap$ATAC_logFC > 0 &
overlap$H3K4me3_logFC > 0 &
overlap$H3K27ac_logFC > 0 &
overlap$ATAC_distanceToTSS < 2500 &
overlap$RNA_logFC > 0
overlap$ATAC_RNA[active_promoters] <- "Active Promoters"
Repressed Promoters (E15.5 < E11.5)
repressed_promoters <- overlap$ATAC_logFC < 0 &
overlap$H3K4me3_logFC < 0 &
overlap$H3K27ac_logFC < 0 &
overlap$H3K27me3_logFC > 0 &
overlap$ATAC_distanceToTSS < 2500 &
overlap$RNA_logFC < 0
overlap$ATAC_RNA[repressed_promoters] <- "Repressed Promoters"
Save the file
saveRDS(object = overlap, file = "output/overlap_anno2.rds")
EnrichedHeatmap
+ ComplexHeatmap
Our function from previous exercise
make_EH <- function(norm_mat, heatmap_cols = c("white", "red"), split_rows = NULL, hm_name, col_fill = "#ffcccc"){
if(length(heatmap_cols) == 2){
col_fun <- colorRamp2(quantile(norm_mat, c(0.01, 0.99), na.rm = T), heatmap_cols)
} else if(length(heatmap_cols) == 3){
col_fun <- colorRamp2(quantile(mat_BS$WGBS_11half, c(0.01, 0.5, 0.99), na.rm = T), heatmap_cols)
} else{
message("Please update function!")
}
vmin <- as.numeric(quantile(norm_mat, c(0.01), na.rm = T))
vmax <- as.numeric(quantile(norm_mat, c(0.99), na.rm = T))
vmid <- (vmin + vmax) / 2
legend_ticks <- c(vmin, vmid, vmax)
EnrichedHeatmap(
mat = norm_mat,
name = hm_name,
row_split = split_rows,
col = col_fun,
width = unit(2, "cm"),
height = unit(8, "cm"),
column_title = hm_name,
column_title_gp = gpar(fontsize = 8, fill = col_fill),
axis_name = c("-1kb", "mid", "1kb"),
heatmap_legend_param = list(
at = legend_ticks,
legend_height = unit(0.5, "cm"),
legend_width = unit(0.1, "cm"),
labels = round(legend_ticks, digits = 1),
title_gp = gpar(fontsize = 8),
labels_gp = gpar(fontsize = 7)
),
top_annotation = HeatmapAnnotation(
lines = anno_enriched(
height = unit(1, "cm"),
axis_param = list(
side = "right",
facing = "inside",
gp = gpar(
fontsize = 7,
lwd = 0.4
)
)
)
)
)
}
ATAC
atac_11h <- make_EH(norm_mat = mat_ATAC$ATAC_11half, hm_name = "AS-E11.5", col_fill = "#ffcccc")
atac_15h <- make_EH(norm_mat = mat_ATAC$ATAC_15half, hm_name = "AS-E15.5", col_fill = "#e6fff2")
H3K4me3
H3K4me1
H3K27me3
H3K27ac
Methylation
Annotation
[1] "Active Promoters" "Inc. Acc." "Dec. Acc."
[4] "Incongruent" "Silent" "Active"
[7] "Repressed" "Gained Enhancers" "Lost Enhancers"
[10] "Repressed Promoters"
split_anno <- factor(split_anno, levels = unique(split_anno)[c(1,10,6,7,8,9,5,4,2,3)])
cols_an <- RColorBrewer::brewer.pal(n = length(unique(split_anno)), name = "Paired")
row_order_eh <- row_order(atac_11h)
Warning: The heatmap has not been initialized. You might have different results
if you repeatedly execute this function, e.g. when row_km/column_km was
set. It is more suggested to do as `ht = draw(ht); row_order(ht)`.
anno_hm <- Heatmap(
mat = split_anno,
col = cols_an,
name = "Annotation",
show_row_names = FALSE,
show_column_names = FALSE,
width = unit(2, "mm"),
height = unit(8, "cm"),
row_order = row_order_eh,
row_title_gp = gpar(fontsize = 0)
)
There are 10 unique colors in the vector `col` and 10 unique values in
`matrix`. `Heatmap()` will treat it as an exact discrete one-to-one
mapping. If this is not what you want, slightly change the number of
colors, e.g. by adding one more color or removing a color.
RNA
rna_hm <- Heatmap(matrix = mat_RNA,
name = "RNA",
cluster_columns = FALSE,
cluster_rows = FALSE,
na_col = "grey",
row_order = row_order_eh,
show_row_names = FALSE,
show_column_names = FALSE,
row_title_rot = 0,
top_annotation = HeatmapAnnotation(
df = colData(rna)[,2,drop = FALSE],
annotation_name_gp = gpar(fontsize = 0)
),
width = unit(2, "cm"),
height = unit(18, "cm"),
heatmap_legend_param = list(
legend_height = unit(0.5, "cm"),
legend_width = unit(0.1, "cm"),
at = c(-10,0,10),
title = "RNA",
title_gp = gpar(fontsize = 8),
labels_gp = gpar(fontsize = 7)
)
)
Combine plots
ht_opt$TITLE_PADDING <- unit(1, "mm")
ht_opt$legend_gap <- unit(3, "mm")
ht_opt$legend_grid_height <- unit(2, "mm")
ht_opt$legend_grid_width <- unit(2, "mm")
ht_opt$HEATMAP_LEGEND_PADDING <- unit(1, "mm")
ht_opt$heatmap_border <- TRUE
draw(
anno_hm +
atac_11h + atac_15h +
h3k4me3_11h + h3k4me3_15h +
h3k4me1_11h + h3k4me1_15h +
h3k27me3_11h + h3k27me3_15h +
h3k27ac_11h + h3k27ac_15h +
rna_hm +
meth_11h + meth_15h,
split = split_anno,
merge_legend = FALSE,
heatmap_legend_side = "bottom"
)
pdf(file = "output/final_heatmap.pdf", width = 22, height = 17)
grid.newpage()
pushViewport(viewport(gp = gpar(lwd = 0.5)))
draw(
anno_hm +
atac_11h + atac_15h +
h3k4me3_11h + h3k4me3_15h +
h3k4me1_11h + h3k4me1_15h +
h3k27me3_11h + h3k27me3_15h +
h3k27ac_11h + h3k27ac_15h +
rna_hm +
meth_11h + meth_15h,
split = split_anno,
merge_legend = FALSE,
heatmap_legend_side = "bottom"
)
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
popViewport()
dev.off()
quartz_off_screen
2
png(filename = "output/final_heatmap.png", width = 27, height = 22, units = "in", res = 330)
grid.newpage()
pushViewport(viewport(gp = gpar(lwd = 0.5)))
draw(
anno_hm +
atac_11h + atac_15h +
h3k4me3_11h + h3k4me3_15h +
h3k4me1_11h + h3k4me1_15h +
h3k27me3_11h + h3k27me3_15h +
h3k27ac_11h + h3k27ac_15h +
rna_hm +
meth_11h + meth_15h,
split = split_anno,
merge_legend = FALSE,
heatmap_legend_side = "bottom"
)
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
Warning: `legend_height` you specified is too small, use the default minimal
height.
popViewport()
dev.off()
quartz_off_screen
2
Question
Look at the plot carefully and try to understand patterns. Can you confirm from the plot that the plot is correct for the Active Promoters
?
Important
You can make all possible categories from this overlapMatrix
. Feel free to make more categories.
Bonus
Important
A reference guide for integrating multiomics data is provided here: Reference Guide