Publication-Ready DEG Visualizations: Volcano Plots, MA Plots & Heatmaps
Tested Stacks:
GATK 4.6.1
Samtools 1.21
Nextflow 24.10
Seurat v5.1
Python 3.12
Prerequisites: Basic Linux CLI & Sequencing Formats
📚 Chapter 9 of 10
0% Course Completed
PLANT BIOTECHNOLOGY • TRACK 20
CHAPTER 08 OF 10
55 min read • 8 Code Examples • ggplot2 & pheatmap Publication-Ready DEG Visualizations: Volcano Plots, MA Plots & Heatmaps
Generating customized MA plots, publication-grade Volcano plots with ggplot2 and EnhancedVolcano, and bidirectional hierarchically clustered heatmaps using pheatmap and ComplexHeatmap.
Phase: Visualization & Heatmaps
Key Learning Deliverables & Competencies
- Constructing MA plots displaying mean expression vs log2FC with shrunken estimates
- Creating publication-grade Volcano plots highlighting key drought transcription factors (DREB, WRKY, NAC)
- Hierarchical clustering (Euclidean distance, Ward.D2) and Z-score scaled expression heatmaps
- Integrating sample metadata annotation bars: Genotype, Drought Stage, and Replicate ID
1. Publishing High-Impact RNA-Seq Visualizations
High-throughput datasets require clear, informative visual summaries. Here we demonstrate how to produce publication-grade figures suitable for high-impact journals (e.g., The Plant Cell, Plant Biotechnology Journal).
2. MA Plots with Moderated Shrinkage
library(DESeq2)
# Standard vs Shrunk MA Plot comparison
par(mfrow = c(1, 2))
plotMA(res_tol_d7, ylim = c(-6, 6), main = "Unshrunk LFC Estimates")
plotMA(res_tol_d7_shrunk, ylim = c(-6, 6), main = "apeglm Moderated Shrinkage")3. Publication-Grade Volcano Plot with Key Plant Transcription Factors
library(EnhancedVolcano)
# Known potato drought regulators to label on the volcano plot
highlight_genes <- c("Soltu.DM.03G014520", # StDREB2A
"Soltu.DM.08G029810", # StWRKY33
"Soltu.DM.05G021100", # StLEA-14
"Soltu.DM.11G005430", # StP5CS (Proline Synthase)
"Soltu.DM.02G031200") # StNAC072
EnhancedVolcano(
res_tol_d7_shrunk,
lab = rownames(res_tol_d7_shrunk),
selectLab = highlight_genes,
x = 'log2FoldChange',
y = 'padj',
pCutoff = 1e-4,
FCcutoff = 1.5,
pointSize = 2.5,
labSize = 4.0,
col = c('grey70', '#10b981', '#06b6d4', '#f43f5e'),
colAlpha = 0.8,
legendPosition = 'bottom',
title = 'Drought-Tolerant Potato: Severe Water Deficit (D7 vs D0)',
subtitle = 'Thresholds: FDR < 1e-4 and |log2FC| > 1.5'
)4. Bidirectional Hierarchical Clustering Heatmap
library(pheatmap)
library(RColorBrewer)
# Extract Variance Stabilizing Transformation (VST) values
vsd <- vst(dds, blind = FALSE)
vst_mat <- assay(vsd)
# Select top 50 most variable drought-responsive genes
top_var_genes <- head(order(rowVars(vst_mat), decreasing = TRUE), 50)
heatmap_matrix <- vst_mat[top_var_genes, ]
# Scale by Z-score across rows
heatmap_z <- t(scale(t(heatmap_matrix)))
# Set up sample metadata annotations
annotation_col <- data.frame(
Genotype = targets$Genotype,
Drought_Stage = targets$Drought_Stage,
row.names = targets$Sample_ID
)
# Plot publication heatmap
pheatmap(
heatmap_z,
annotation_col = annotation_col,
color = colorRampPalette(rev(brewer.pal(n = 9, name = "RdYlBu")))(100),
show_rownames = TRUE,
fontsize_row = 7,
cluster_cols = TRUE,
cluster_rows = TRUE,
main = "Top 50 Drought-Responsive Genes in Solanum tuberosum"
)
⚠️
Common Pitfalls & Troubleshooting Checklist
- Java Heap Exhaustion (GATK / Picard): If processes terminate with
java.lang.OutOfMemoryError, set your environment variable explicitly:export _JAVA_OPTIONS="-Xmx16g -Djava.io.tmpdir=/tmp". - Index Timestamp Mismatch: If tools complain that a BAM index is missing or out of date, regenerate with
samtools index -@ 4 sample.bam. - Conda Channel Conflicts: Avoid ABI incompatibilities between bioconda and conda-forge by setting strict priority:
conda config --set channel_priority strict. - Chromosome Naming Contamination: Always verify whether reference FASTA headers use
chr1or1; divergent naming causes silent alignment drops.
Was this guide helpful to your research?
Help us maintain 100% accurate, peer-reviewed bioinformatics standards.