loukesio
ggvolc
R

๐ ๐ ๐ฏ๐จ๐ฅ๐œ effortlessly translates differential expression datasets and RNAseq data into informative volcano plots. Highlight genes of interest with unprecedented ease. With just a single line of code, visualize complex datasets, gaining deeper insights and simplifying data representation

Last updated Jul 5, 2026
72
Stars
4
Forks
0
Issues
0
Stars/day
Attention Score
72
Language breakdown
R 96.2%
Dockerfile 3.8%
โ–ธ Files click to expand
README

CRAN</em>Status_Badge License: MIT CRAN downloads

Install the ggvolc package

Install the package using the following commands

r

you can install ggvolc from CRAN

install.packages("ggvolc")

if you want to install the developmenetal version please use

devtools::install_github("loukesio/ggvolc")

and load it

library(ggvolc)


How do I start?

ggvolc turns the results of a differential-expression analysis โ€” from DESeq2, edgeR, or limma โ€” into a clean, publication-ready volcano plot. From there you can highlight genes, auto-label the top hits, attach a gt table, or make the whole thing interactive. Start by loading the library and exploring the two example datasets that ship with the package:

console
library(ggvolc)
#> Welcome to ggvolc version 0.3.0 !
#>
#>                                 888
#>                                 888
#>                                 888
#>  .d88b.   .d88b.  888  888  .d88b.  888  .d8888b
#> d88P"88b d88P"88b 888  888 d88""88b 888 d88P"
#> 888  888 888  888 Y88  88P 888  888 888 888
#> Y88b 888 Y88b 888  Y8bd8P  Y88..88P 888 Y88b.
#>  "Y88888  "Y88888   Y88P    "Y88P"  888  "Y8888P
#>      888      888
#> Y8b d88P Y8b d88P
#>  "Y88P"   "Y88P"
#>

data(all_genes) # data.frame that contains the output of differentially expressed genes head(all_genes,5) # have a look at the first 5 rows

#> genes baseMean log2FoldChange lfcSE stat pvalue #> 1 GCR1 7201.5782 2.244064 0.2004959 11.192564 4.434241e-29 #> 2 OPI10 1009.4171 -2.257454 0.2096469 -10.767889 4.880607e-27 #> 3 AGA2 249.1173 3.829474 0.3623263 10.569132 4.143136e-26 #> 4 FIM1_1376 5237.5035 2.550409 0.2560379 9.961059 2.256459e-23 #> 5 HMG1 10838.1037 2.214300 0.2229065 9.933763 2.968371e-23 #> padj #> 1 2.153711e-25 #> 2 1.185255e-23 #> 3 6.707736e-23 #> 4 2.739905e-20 #> 5 2.883475e-20

data(attention_genes) # here is a data.frame with genes that I want to mention to the volcano plot head(attention_genes,5) # have a look at the first five rows #> genes baseMean log2FoldChange lfcSE stat pvalue #> 1 THI13 480.5194 1.585811 0.5219706 3.038122 2.380572e-03 #> 2 FBP1 22710.8428 -2.366733 0.3533032 -6.698871 2.100354e-11 #> 3 TRA1 4491.1343 -1.410696 0.4384316 -3.217595 1.292700e-03 #> 4 YDR222W 591.2289 -4.045918 0.9133881 -4.429572 9.442026e-06 #> 5 BRL1 4434.7712 2.375919 0.5037264 4.716686 2.397176e-06 #> padj #> 1 1.371582e-02 #> 2 3.290780e-09 #> 3 8.565681e-03 #> 4 1.819838e-04 #> 5 5.850796e-05

Created on 2023-08-11 with reprex v2.0.2

1. Plot a simple volcano plot!

Pass a single data frame and every gene is coloured by significance โ€” down, up, or not significant.

r
ggvolc(all_genes)

2. Add the genes of attention.

Supply a second data frame to outline and label the genes you care about.

r
ggvolc(allgenes, attentiongenes)

3. Add segments to indicate areas of significance.

Turn on add_seg to draw the fold-change and significance thresholds.

r
ggvolc(allgenes, attentiongenes, add_seg = TRUE) +
  labs(title="Add segments of significance")

4. Indicate the size of point based on the log2FoldChange column.

Scale point size by effect size with size_var = "log2FoldChange".

r
ggvolc(allgenes, attentiongenes, sizevar = "log2FoldChange", addseg = TRUE)

5. Indicate the size of the point based on the pvalue.

Or scale it by significance with size_var = "pvalue".

r
ggvolc(allgenes, attentiongenes, sizevar = "pvalue", addseg = TRUE)

6. Add a table with the genes of interest.

r
plot <- ggvolc(allgenes, attentiongenes, add_seg = TRUE) +
  labs(title="Add a table with the genes of interest")

plot %>% genestable(attentiongenes)

The gene table is rendered with gt and composed with patchwork, so the result is a single object you can style further or save with ggplot2::ggsave().

Instead of curating your own set of genes, you can let genes_table() pick the most significant ones automatically with top_n. Pass the full DE table and it selects the top genes by sig_col (defaults to padj, falling back to pvalue). Use dir = "each" to take the top N up- and down-regulated genes.

r
plottop <- ggvolc(allgenes, labeltop = 10, addseg = TRUE) +
  labs(title = "Top 10 most significant genes")

plot_top %>% genestable(allgenes, top_n = 10)

7. Works with DESeq2, edgeR, and limma out of the box

ggvolc() and genes_table() accept the output of all three major differential-expression pipelines directly โ€” column names are auto-detected and mapped internally, so no manual renaming is needed. Gene identifiers held in row names (as edgeR/limma often do) are promoted to a genes column automatically.

| Pipeline | Fold change | p-value | adjusted p | expression | |----------------------|------------------|-----------|-------------|------------| | DESeq2 (results()) | log2FoldChange | pvalue | padj | baseMean | | edgeR (topTags()) | logFC | PValue | FDR | logCPM | | limma (topTable()) | logFC | P.Value | adj.P.Val | AveExpr |

The package ships edger_genes, an example topTags()-style table, so you can see this directly. In your own analysis you would pass the real thing:

r

edgeR: pass topTags()$table straight in

edger_res <- as.data.frame(edgeR::topTags(qlf, n = Inf)) ggvolc(edger_res)
r
data(edger_genes)          # an edgeR topTags()-style table (genes in the rownames)
head(edger_genes, 3)
#>           logFC  logCPM       PValue          FDR
#> GCR1   2.244064 12.8143 4.434241e-29 2.153711e-25
#> OPI10 -2.257454  9.9807 4.880607e-27 1.185255e-23
#> AGA2   3.829474  7.9665 4.143136e-26 6.707736e-23

ggvolc(edgergenes, labeltop = 8, add_seg = TRUE, title = "edgeR input")

8. Significance on the adjusted p-value (FDR) โ€” the default

ggvolc() calls significance on the adjusted p-value (FDR) by default โ€” the right cutoff for most DE workflows โ€” and the y-axis and the significance line follow along, so the plot stays consistent. Prefer the raw p-value? Set sig_col = "pvalue".

r
ggvolc(allgenes, addseg = TRUE)   # significance on padj (FDR) by default

If your table has no adjusted-p column, ggvolc automatically falls back to the raw p-value.

ggvolc() is also robust to p-values of exactly 0 (which DESeq2/edgeR can emit for the strongest genes): instead of silently dropping them, their -log10 value is capped so they stay pinned near the top of the plot.

9. Automatically label the top genes

No need to build a separate data frame โ€” label_top highlights and labels the N most significant genes for you, and label_dir lets you pick the direction.

r

top 10 overall

ggvolc(allgenes, labeltop = 10, add_seg = TRUE, title = "Top 10 hits")

r

top 8 up- and top 8 down-regulated

ggvolc(allgenes, labeltop = 8, labeldir = "each", addseg = TRUE, title = "Top 8 up + 8 down")

label_dir accepts "both" (default), "up", "down", or "each".

10. Make it interactive

Set interactive = TRUE to get an ggiraph widget โ€” hover any point to see the gene name and its statistics. ggiraph is an optional dependency (install it with install.packages("ggiraph")).

r
ggvolc(allgenes, attentiongenes, interactive = TRUE)
Note: GitHub canโ€™t run the widget, so the image below is a static preview.
The live, hover-to-inspect version runs in RStudio and on the
package website.

Learn more

reference and a getting-started article with every example (including the live interactive volcano). โ€” docker pull ghcr.io/loukesio/ggvolc:latest for a ready-to-run RStudio environment with ggvolc pre-installed. reports and feature requests are welcome.
๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท loukesio/ggvolc ยท Updated daily from GitHub