omics.co.in logo omics.co.in

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 chr1 or 1; divergent naming causes silent alignment drops.
Was this guide helpful to your research?
Help us maintain 100% accurate, peer-reviewed bioinformatics standards.
📝 Propose Edit on GitHub ↗