bio-data-visualization-volcano-and-ma-plots
Build volcano and MA plots from differential-expression / association results with LFC shrinkage, FDR-adjusted thresholds, sensible label placement, and axis-truncation conventions. Covers EnhancedVolcano, ggplot2, matplotlib, and the apeglm/ashr/normal shrinkage decision. Use when visualizing differential-expression results (RNA-seq, ChIP-seq, ATAC-seq, proteomics) or any per-feature effect-size + p-value table.
npx skills add BioTender-max/awesome-bio-agent-skills --skill volcano-and-ma-plots --agent claude-code
Same command for any agent — swap --agent for codex, cursor, copilot.
Weekly change comes from our own snapshots, not the repository page — it measures attention, not adoption.
What it does
Build volcano and MA plots from differential-expression / association results with LFC shrinkage, FDR-adjusted thresholds, sensible label placement, and axis-truncation conventions. It covers EnhancedVolcano, ggplot2, matplotlib, and the apeglm/ashr/normal shrinkage decision. Use when visualizing differential-expression results (RNA-seq, ChIP-seq, ATAC-seq, proteomics) or any per-feature effect-size + p-value table.
How it works
The skill instructs plotting tools to:
- Choose an effect estimate for the x-axis (raw vs shrunken LFC) and a significance measure for the y-axis (raw p, adjusted p, or s-value), with categories encoded by direction (color by Up/Down) and labeling strategies (top-N or pre-selected genes).
- Prefer shrunken LFC using lfcShrink() with type in Apeglm/Ashr/normal, and recommend ordering and coloring to reflect significance and direction.
- Produce volcano plots with ggplot2 and ggrepel, including pre-selection of labels via a top-N or user-provided gene list, and apply non-overlapping labeling via geom_text_repel with max.overlaps settings. Ensure lines and scales reflect FDR thresholds when using padj as y-axis, and use -log10(fdr) for thresholds.
- Provide EnhancedVolcano usage, noting Gotchas (selectLab respects thresholds; y = 'padj' is preferable; x-limits should be symmetric).
- Offer MA plots with DESeq2 plotMA guidance and a Python ma_plot example that colors by significance and uses rasterized points for large datasets.
- Include failure modes and fixes for common mistakes (unshrunken LFC, wrong threshold line, labeling limits, ggrepel overlaps, extreme p-values, and outdated shrinkage priors).
When to use it
Use when visualizing differential-expression results (RNA-seq, ChIP-seq, ATAC-seq, proteomics) or any per-feature effect-size + p-value table.
What it can touch
The skill references tools and functions in:
- R: EnhancedVolcano(), ggplot2, ggrepel, DESeq2
- Python: matplotlib.pyplot, numpy
- R-specific shrinkage: lfcShrink() with type = 'apeglm' or 'ashr' or 'normal'
Caveats
Version compatibility notes specify DESeq2 v1.28+ with apeglm as default; ensure libraries match tested references (DESeq2, EnhancedVolcano, ggplot2, ggrepel, matplotlib, numpy, adjustText, apeglm, ashr). Gotchas include: selectLab filtering by pCutoff and FCcutoff; y-axis choice affecting threshold interpretation; symmetric x-limits recommended; use of max.overlaps = Inf to avoid missing labels.
## Version Compatibility Reference examples tested with: DESeq2 1.42+, EnhancedVolcano 1.20+, ggplot2 3.5+, ggrepel 0.9.5+, matplotlib 3.8+, numpy 1.26+, adjustText 1.1+, apeglm 1.28+, ashr 2.2+. Before using code patterns, verify installed versions match. If versions differ: - Python: `pip show <package>` then `help(module.function)` to check signatures - R: `packageVersion('<pkg>')` then `?function_name` to verify parameters If code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying. # Volcano and MA Plots **"Plot differential-expression results"** -> Place per-feature shrunken effect estimate on the x-axis and a significance measure (-log10 padj or -log10 p) on the y-axis. The decision space spans which effect estimate (raw vs shrunken), which significance measure (raw p vs adjusted vs s-value), how to encode categories (color by direction, not by gradient), how to label (top-N is rarely informative), and how to handle the tail (extreme p compresses the plot). - R: `EnhancedVolcano::EnhancedVolcano()`, `ggplot2 + ggrepel`, `DESeq2::plotMA()` - Python: `matplotlib.scatter` with `adj
- Version Compatibility
- The Single Most Important Modern Insight -- Plot Shrunken LFC
- Shrinkage Method Selection
- Decision Tree by Scenario
- Volcano with ggplot2 + ggrepel
- EnhancedVolcano -- Production Use and Its Gotchas
- MA Plot -- The Underused Diagnostic
- Per-Method Failure Modes
- Unshrunken LFC plotted as volcano
- Raw p threshold line drawn on adjusted axis
- Top-N-by-p selects low-effect-size hits
- ggrepel max.overlaps silently drops labels
- Extreme p-values compress the upper axis
- lfcShrink(type='normal') on a modern DESeq2
What does the bio-data-visualization-volcano-and-ma-plots skill do?
Build volcano and MA plots from differential-expression / association results with LFC shrinkage, FDR-adjusted thresholds, sensible label placement, and axis-truncation conventions. Covers EnhancedVolcano, ggplot2, matplotlib, and the apeglm/ashr/normal shrinkage decision. Use when visualizing differential-expression results (RNA-seq, ChIP-seq, ATAC-seq, proteomics) or any per-feature effect-size + p-value table.
How do I install it?
Run `npx skills add BioTender-max/awesome-bio-agent-skills --skill volcano-and-ma-plots --agent claude-code` — it drops the skill into your project so the agent can pick it up. Swap the --agent value for codex, cursor or copilot if you use one of those.
Where does this skill come from?
From BioTender-max/awesome-bio-agent-skills, a repository with 135 stars. We read it straight from the repository tree rather than a submitted listing, so what you see here is what is actually published.
Is a popular skill a good skill?
Not necessarily. Stars measure attention, not adoption — a repository can trend for a week and be abandoned. That is why we show the weekly change from our own snapshots next to the total, instead of a single flattering number.
