Tool: EnhancedVolcano: Publication-ready volcano plots with enhanced colouring and labeling
31
gravatar for Kevin Blighe
22 months ago by
Kevin Blighe61k
Kevin Blighe61k wrote:

last update: June 2, 2019

EnhancedVolcano

EnhancedVolcano is now on Bioconductor. The function was well received here on Biostars (primarily here: A: Volcano plot help code ), which originally gave me the impetus to go for a Bioconductor submission.

INSTALLATION

Devel (catch most recent changes):

devtools::install_github('kevinblighe/EnhancedVolcano')

Release (from Bioconductor):

BiocManager::install('EnhancedVolcano')

---------------------------------------------

ex12-1 ex10-1 ex13-1

---------------------------------------------

GitHub

https://github.com/kevinblighe/EnhancedVolcano

Bioconductor

https://bioconductor.org/packages/release/bioc/html/EnhancedVolcano.html

Vignette

https://bioconductor.org/packages/release/bioc/vignettes/EnhancedVolcano/inst/doc/EnhancedVolcano.html


Should anyone wish to provide feedback and / or suggestions for future development, please do so. Credit will always be given where it is due.

Kevin

ADD COMMENTlink modified 22 days ago by camillab.10 • written 22 months ago by Kevin Blighe61k
1

Great tool, thanks for putting it together!

My DEseqDataSet is actually a set of peaks instead of transcripts that all have a unique identifier going out to 6 figures, I was wondering if there was a way to use selectLab() to create custom labels such as TF names for factors I know to bind within those peaks or even small representations of their PWMs - though the former would be sufficient for the moment - or does that have to come from an additional metadata column in DEseqDataSet? Thanks!

ADD REPLYlink modified 19 months ago • written 19 months ago by rbronste360
2

Hey, thanks for the comments. My colleague Myles back in London deserves the credit for the initial idea of putting this together. selectLab() will just match up to whatever you have passed to the required lab parameter. So, it can be anything really, but there is no functionality to automatically pull in TF names. That is a good idea, though, and it would show in a nice way which TFs were up- or down-regulated.

I mean, this package is only released for a few weeks at this stage, and I'm fairly open as to where it could be developed further. I was hoping to build something as comprehensive as the ComplexHeatmap package.

ADD REPLYlink written 19 months ago by Kevin Blighe61k
1

Hi Kevin,

Thanks again for the amazing tool!

Can I use EnhancedVolcano with plotly? I assume it's built using ggplot2, and I've tried to do:

ggplotly(plot) where plot is a volcano plot made using EnhancedVolcano.

I get the following error message though:

Error in unique.default(x) :
unique() applies only to vectors
In addition: Warning messages:
1: In if (nchar(axisTitleText) > 0) { :
  the condition has length > 1 and only the first element will be used
2: In if (nchar(axisTitleText) > 0) { :
  the condition has length > 1 and only the first element will be used

Being able to use these volcano plots with plotly would be super useful! Especially when there are too many DEGs and it really makes labeling messy.

Thanks!

ADD REPLYlink modified 10 months ago by RamRS27k • written 15 months ago by unawaz50

EnhancedVolcano does indeed return a ggplot2 object, on which extra features can be added. It also utilises ggrepel - perhaps that is the missing link? I have not tried with plotly but will make an attempt later to see how to coerce the volcano object to work with plotly.

I believe there are a few tutorials around where plotly is used to generate a volcano, though. I think that Stephen Turner had one, but cannot find it right now.

ADD REPLYlink modified 15 months ago • written 15 months ago by Kevin Blighe61k
1

Aha! Thank you so much, it's working now :)

ADD REPLYlink written 10 months ago by s.muroy10
1

Please use Add Comment or Add Reply as appropriate instead of Add Answer.

ADD REPLYlink written 10 months ago by RamRS27k

and i already used it....

ADD REPLYlink written 22 months ago by krushnach80810
1

Good work dude!

ADD REPLYlink written 22 months ago by Kevin Blighe61k

Hi Kevin,

Great tool! I've been pretty much using it for all my volcano plots. I wanted to know if there was a way to use EnhancedVolcanos with results from sleuth?

cheers!

ADD REPLYlink written 17 months ago by unawaz50

You're welcome. Yes, most likely there is a way. What are the columns in the output of Sleuth?

ADD REPLYlink written 17 months ago by Kevin Blighe61k

This is the output for sleuth, where b is equivalent to Log2FC

ens_gene    ext_gene    target_id   pval    qval      b se_b    mean_obs    var_obs tech_var    sigma_sq    smooth_sigma_sq final_sigma_sq
ADD REPLYlink modified 10 months ago by RamRS27k • written 17 months ago by unawaz50

Hey, well, you have at least 2 required columns:

  • ens_gene (label)
  • pval (y)

What is missing is the fold-change for x! I have never used Sleuth, however, I searched the Web forums and am surprised to see that the Sleuth developers do not output a fold-change for Sleuth's results. You may consider using a different differential expression analysis program.

ADD REPLYlink modified 17 months ago • written 17 months ago by Kevin Blighe61k

That's unfortunate. Thanks for looking though!

ADD REPLYlink written 17 months ago by unawaz50

You could likely still use the b value, in which case you should change the x-axis label too. You may want to read through this thread on Google Groups: https://groups.google.com/forum/#!topic/kallisto-sleuth-users/kWodd7CQejE (Harold Pimentel is Sleuth developer)

ADD REPLYlink written 17 months ago by Kevin Blighe61k

Hi Kevin, Thanks for this great package. A basic question: you specify in the vignette that the default p-value cut-off is 0.05, but from the default plot, it looks to me as if it were 0.005. Is this a misunderstanding on my part? Best wishes, Patrick

ADD REPLYlink written 13 months ago by patrick.kraetschmer10

Hey Patrick, thanks for noticing that. The default is actually:

pCutoff = 10e-6

I just need to update the text in the vignette!

ADD REPLYlink written 13 months ago by Kevin Blighe61k
1

Thanks, Kevin, I've just seen that, having read through the whole vignette: all makes sense!

ADD REPLYlink written 13 months ago by patrick.kraetschmer10

I am updating that part of the vignette right now, so, the change will come through on the Vignette on GitHub in the next few minutes: https://github.com/kevinblighe/EnhancedVolcano

It will be until Bioc 3.10 before it is changed on the main Bioconductor branch.

ADD REPLYlink written 13 months ago by Kevin Blighe61k

Awesome package, Kevin! Is it possible to remove the log2FC cutoff and lines?

ADD REPLYlink written 13 months ago by mehul.kumar0
1

Hey, thank you!

To remove all cut-off lines, you just need to do:

EnhancedVolcano(..., gridlines.major = FALSE, gridlines.minor = FALSE, ...)

If you want to disable the actual cut-off itself (and, thus, the colouring of the points based on the cut-off), then I may recommend the use of colCustom ? - there is an example in the vignette:

Another possibility is to set FCcutoff to something crazy like 1 000 000 such that nothing passes it.

ADD REPLYlink written 13 months ago by Kevin Blighe61k

Is there any chance to change tick intervals for both horizontal and vertical axes? And thanks a lot this is awsome!

ADD REPLYlink written 11 months ago by fr130

Hey, EnhancedVolcano is [thankfully] fully compatible with ggplot2 functionality. So, to modify, e.g., the y-axis, you can do:

p <- EnhancedVolcano(res1,
    lab = rownames(res1),
    x = 'log2FoldChange',
    y = 'pvalue',
    xlim = c(-5, 8))

p + scale_y_continuous(
  name = bquote(~-Log[10]~italic(P)),
  limits=c(0, 100),
  breaks=c(0, 33, 40, 49, 77, 88))

ddd

Hopefully this helps!

ADD REPLYlink written 11 months ago by Kevin Blighe61k

Hi Kevin, EnhancedVolcano package was really helpful. I have two doubts:

  1. when I used the below option legend=c('NS','Log (base 2) fold-change','P value', 'P value & Log (base 2) fold-change') it has printed Log (base 2) but not the Log2 (subscript). May I know how to do it.

  2. when I have modified pointSize = c(ifelse(res$log2FoldChange>2, 8, 1)) as pointSize = c(ifelse(res$log2FoldChange>2 & res$padj>0.05, 8, 1)) it worked. But when I have used pointSize = c(ifelse(res$log2FoldChange>2 & res$log2FoldChange<-2 & res$padj>0.05, 8, 1)) it did not work. May I know how to do it.

Thanks in advance!

ADD REPLYlink written 10 months ago by bhanu.chandra120
1

when I used the below option legend=c('NS','Log (base 2) fold-change','P value', 'P value & Log (base 2) fold-change') it has printed Log (base 2) but not the Log2 (subscript). May I know how to do it.

I implemented that a few days ago, so, it is only currently in the development version, which you can install via:

devtools::install_github('kevinblighe/EnhancedVolcano')

Note: you may have to install the devtools package There are now 2 parameters for the legend:

legend = c("NS","Log2 FC","P","P & Log2 FC")
legendLabels = c('NS', expression(Log[2]~FC),
    "p-value", expression(p-value~and~log[2]~FC))

Expressions (equations, super- and sub-script, etc) can only be used in legendLabels. This may seem silly to have 2 parameters for legend, but it relates to how ggplot2 (which is the underlying 'engine' behind EnhancedVolcano) utilises legends.

---------------------------

---------------------------

when I have modified pointSize = c(ifelse(res$log2FoldChange>2, 8, 1)) as pointSize = c(ifelse(res$log2FoldChange>2 & res$padj>0.05, 8, 1)) it worked. But when I have used pointSize = c(ifelse(res$log2FoldChange>2 & res$log2FoldChange<-2 & res$padj>0.05, 8, 1)) it did not work. May I know how to do it.

I think that you may want to do:

pointSize = c(ifelse(abs(res$log2FoldChange)>2 & res$padj>0.05, > 8, 1))
ADD REPLYlink modified 10 months ago • written 10 months ago by Kevin Blighe61k

Hi Kevin,

Thank you for the response.

Both of your suggestions worked :)

pointSize = c(ifelse(abs(res$log2FoldChange)>2 & res$padj>0.05, > 8, 1))

I guess, there should not be '>' before 8.

Thank you!

ADD REPLYlink modified 9 months ago by RamRS27k • written 10 months ago by bhanu.chandra120

Great. Oh, yes, not sure why I put the > there.

ADD REPLYlink written 10 months ago by Kevin Blighe61k

Hi Kevin,

I have two questions:

  1. When I plot with results object (after shrinkage), the number of genes (visible on the plot) passing the cutoff criteria are relatively less when compared to the plot with results object (without shrinkage). The graph looks nice with shrinkage and much more dispersed without shrinkage. May I know how to overcome this issue.

  2. When we use FCcuoff = 1.2, it represents log2FC (x-axis). But I want to set the cutoff for upregulation as log2FC = 0.585 (FC is >1.5) and downregulation as log2FC = -1 (FC < 0.5). Is it possible to give different log2FC cutoff values for up and downregulation?

Thanks in advance and looking forward to hearing from you.

ADD REPLYlink written 9 months ago by bhanu.chandra120

Hey Bhanu,

The first question is more for the DESeq2 developer. However, the idea of lfcshrink() is, generally, to produce more realistic fold changes

For the second part, you would have to avail of the colCustom parameter and assign the colours before running the EnhancedVolcano() function. You could then also draw your own custom cutoff fold change lines with the following:

vline
vlineType
vlineCol
vlineWidth

To get rid of the main cut-off lines, just set cutoffLineType = 'blank'

There are many examples in the vignette: https://github.com/kevinblighe/EnhancedVolcano

ADD REPLYlink written 9 months ago by Kevin Blighe61k
1

Hi Kevin,

Thank you for the response. Now I could use the colCustom parameter and do the required by following the examples in the Github. Thank you again!

ADD REPLYlink written 9 months ago by bhanu.chandra120

Hi Kevin,

Thank you so much for the EnhancedVolcano package - it's great! I have a quick question, I need to generate a high-res image of my volcano plot for publication and was wondering how to do that from EnhancedVolcano. I'm an R newbie and would very much appreciate any tips! I apologize if this is a bit off-topic.

Thank you! Sandra

ADD REPLYlink written 10 months ago by s.muroy10

Hey Sandra, I would generate the figure as a pdf with the pdf() function. PDFs are vector-based, not pixelated, so, they look 'perfect; when zoomed in and can also be easily manipulated by a journal graphics team. Also make use of the width and height arguments that are passed to the pdf() function.

pdf(out.pdf, width = 6, height = 9)
  EnhancedVolcano(...)
dev.off()

Alternatively, I show how one can generate multiple volcanos side-by-side in the vignette via grid and gridExtra, e.g., HERE.

ADD REPLYlink modified 10 months ago • written 10 months ago by Kevin Blighe61k

Hi Kevin, Thank you so much for the quick reply. The pdf looks beautiful! I have another question, I'm trying to add connectors (to fit more gene name labels)

EnhancedVolcanobaseline.no.NA,
               lab=baseline.no.NA[, 1],
                x = 'log2FoldChange',
                y = 'padj',
                xlim = c(-11, 11),
                xlab = bquote(~Log[2]~ 'fold change'),
                ylab = bquote(~-Log[10]~adjusted~italic(P)),
                pCutoff = 0.01, #padj 
                FCcutoff = 1.5,
                transcriptPointSize = 2.0,
                transcriptLabSize = 3.0,
                legend=c('NS','Log2 FC','Adjusted p-value',
                         'Adjusted p-value & Log2 FC'),
                legendPosition = 'top',
                legendLabSize = 12,
                legendIconSize = 3.0,
                gridlines.major = FALSE,
                gridlines.minor = FALSE,
                drawConnectors = TRUE,
                widthConnectors = 0.2,
                colConnectors = 'grey30')

but it gives me an error message:

Error in EnhancedVolcanobaseline.no.NA, lab = baseline.no.NA[, 1], x = "log2FoldChange",  : 
  unused argument (drawConnectors = TRUE)

Not sure what I'm doing wrong. Works great otherwise. Thanks again!

ADD REPLYlink modified 10 months ago by Kevin Blighe61k • written 10 months ago by s.muroy10

Great! Oh, which version are you using? - I changed the name of that argument. In your version, it may be DrawConnectors.

You can install the most up to date version of the package with:

devtools::install_github('kevinblighe/EnhancedVolcano')
ADD REPLYlink written 10 months ago by Kevin Blighe61k

aha! thank you so much, it's working now :)

ADD REPLYlink written 10 months ago by s.muroy10

Hi Kevin,

I frequently face the following error:

Error in grid.Call(C_convert, x, as.integer(whatfrom), as.integer(whatto),  : 
  Viewport has zero dimension(s)

Can you please suggest on how to rectify it?

ADD REPLYlink modified 9 months ago by RamRS27k • written 9 months ago by bhanu.chandra120

Hey, which code are you running, exactly?

ADD REPLYlink written 9 months ago by Kevin Blighe61k
# set the base colour as 'black'
keyvals <- rep('#000000', nrow(res_A_W_lfc))

# set the base name/label as 'NS'
names(keyvals) <- rep('NS', nrow(res_A_W_lfc))

# modify keyvals for variables with fold change > 1.5
keyvals[which(res_A_W_lfc$log2FoldChange > 0.585 &
                res_A_W_lfc$padj < 0.05)] <- '#E50000'
names(keyvals)[which(res_A_W_lfc$log2FoldChange > 0.585 &
                       res_A_W_lfc$padj < 0.05)] <- 'Up'

# modify keyvals for variables with fold change < -0.66
keyvals[which(res_A_W_lfc$log2FoldChange < -0.585 &
                res_A_W_lfc$padj < 0.05)] <- '#3C84FF'
names(keyvals)[which(res_A_W_lfc$log2FoldChange < -0.585 &
                       res_A_W_lfc$padj < 0.05)] <- 'Down'

# Selected genes to represent
s_genes <- c('abo', 'Ace')

# Volcano plots
EnhancedVolcano(res_A_W_lfc,
                x = 'log2FoldChange', y = 'padj',
                lab = rownames(res_A_W_lfc), selectLab = s_genes,
                xlim = c(-4, 4), ylim = c(0, 25),
                xlab = bquote(~Log[2]~ 'Fold Change'),
                ylab = bquote(~-Log[10]~italic(P)),
                axisLabSize = 75,
                title = 'Adult_A_W', subtitle = ' ',
                titleLabSize = 75,
                caption = bquote(~Log[2]~ 'FC cutoff, 0.585; padj cutoff, 0.05'), captionLabSize = 40,
                pCutoff = 0.05, pLabellingCutoff = pCutoff,
                FCcutoff = 0.585,
                cutoffLineType = 'longdash', cutoffLineCol = 'black',
                cutoffLineWidth = 1,
                pointSize = c(ifelse(abs(res_A_W_lfc$log2FoldChange) > 0.585 & res_A_W_lfc$padj < 0.05, 8, 4)),
                labSize = 30,
                labCol = c('black', 'black'),
                labFace = 'plain',
                colCustom = keyvals,
                colAlpha = 0.6,
                legend=c("NS", "Log2 FC", "padj", "padj & Log2 FC"),
                legendLabels = c('NS', expression(Log[2]~FC),
                                 "padj", expression(padj~and~Log[2]~FC)),
                legendPosition = 'right',
                legendLabSize = 50, legendIconSize = 30,
                gridlines.major = F, gridlines.minor = F,
                border = 'full', borderWidth = 5, borderColour = 'black',
                drawConnectors = T, widthConnectors = 4,
                colConnectors = 'yellow')
ADD REPLYlink modified 9 months ago by RamRS27k • written 9 months ago by bhanu.chandra120
2

Please use the formatting bar (especially the code option) to present your post better. You can use backticks for inline code (`text` becomes text), or select a chunk of text and use the highlighted button to format it as a code block. I've done it for you this time.
code_formatting

ADD REPLYlink written 9 months ago by RamRS27k

Thank you Ram :). I will take it as a learning experience.

ADD REPLYlink written 9 months ago by bhanu.chandra120

Whoa! I think that I saw the problem instantly when I re-ran using my own dataset. Here is what I got:

a

Your label sizes are way too large. Here it is with smaller label sizes:

EnhancedVolcano(res_A_W_lfc,
  x = 'log2FoldChange', y = 'padj',
  lab = rownames(res_A_W_lfc), selectLab = s_genes,
  xlim = c(-4, 4), #ylim = c(0, 25),
  xlab = bquote(~Log[2]~ 'Fold Change'),
  ylab = bquote(~-Log[10]~italic(P)),
  axisLabSize = 12,
  title = 'Adult_A_W', subtitle = ' ',
  titleLabSize = 12,
  caption = bquote(~Log[2]~ 'FC cutoff, 0.585; padj cutoff, 0.05'), captionLabSize = 10,
  pCutoff = 0.05, pLabellingCutoff = pCutoff,
  FCcutoff = 0.585,
  cutoffLineType = 'longdash', cutoffLineCol = 'black',
  cutoffLineWidth = 1,
  pointSize = c(ifelse(abs(res_A_W_lfc$log2FoldChange) > 0.585 & res_A_W_lfc$padj < 0.05, 5, 1)),
  labSize = 6,
  labCol = c('black', 'black'),
  labFace = 'plain',
  colCustom = keyvals,
  colAlpha = 0.6,
  legend=c("NS", "Log2 FC", "padj", "padj & Log2 FC"),
  legendLabels = c('NS', expression(Log[2]~FC),
    "padj", expression(padj~and~Log[2]~FC)),
  legendPosition = 'right',
  legendLabSize = 12, legendIconSize = 12,
  gridlines.major = F, gridlines.minor = F,
  border = 'full', borderWidth = 2, borderColour = 'black',
  drawConnectors = T, widthConnectors = 2,
  colConnectors = 'gold')

hhh

ADD REPLYlink modified 9 months ago • written 9 months ago by Kevin Blighe61k
1

Hi Kevin, Thank you! It is working now. Regards, Bhanu

ADD REPLYlink written 9 months ago by bhanu.chandra120

Hi,

Does anyone know how to colour points that have FC>2.5 AND are above the p-value cut-off in 1 colour, and at the same time use a different colour for genes with FC<2.5 AND are above the p-value cut-off? I can see how to do the former from the instructions above, and colour by FC, but not both FC and p-value. I tried using keyvals for this but keep getting error messages.

Also, my labelling only uses row numbers rather than the rowname. I have gene symbols rather than ENS numbers - could this be the problem?

Thanks in advance! Rebecca

ADD REPLYlink written 5 months ago by becki.drummond0

Hello, the way to do this is via keyvals. Can you paste a sample of your data, and also the error messages that you have been receiving?

The 'ENS' IDs are Ensembl gene IDs. The IDs that you use can be anything, but I have not tested EnhancedVolcano in situations where there are no gene names at all.

ADD REPLYlink written 5 months ago by Kevin Blighe61k

Hi, thanks for such a pretty and clear volcano plot! I am using it in my project write up.

I am using labelled volcano as my major one and I want smaller volcanos just to see trends in different conditions without labels, but I want to make the plot look consistent.

I was wondering if I can remove the labels of genes? I tried to remove 'lab=rownames(mydata)' in R but it keeps giving me errors. I tried putting it as <na> but it also did not work.

I'm sorry if it is a really basic question, I am a complete beginner in R coding:'(

Thank you.

ADD REPLYlink modified 4 months ago • written 4 months ago by soyon.kim.140

Hey, sure thing and no problem, you just need to use:

lab = NA
ADD REPLYlink written 4 months ago by Kevin Blighe61k

Hi, I would like to have all point log2FC >= 1 and p value 0.05 in one color and all log2FC <= -1 and p value 0.05 in another one. I tried to run the code above but it gives me this error. I am able to run a classic enhanced plot with the green/blue/red color. if I remove the labels part, it gives me this error:

Error: Aesthetics must be either length 1 or the same as the data (1418): colour

if I include the "labels" part :

Error in EnhancedVolcano(res, x = "log2FC", y = "p_value", lab = NA, xlim = c(-12, : unused argument (legend = c("NS", "Log2FC", "pvalue", "pvalue & Log2FC"))

I wanted to get the same volcano plot as previously shown but I cannot get it.

# set the base colour as "black"
keyvals <- rep("#000000", nrow(res))

# set the base name/label as "NS"
names(keyvals) <- rep("NS", nrow(res))

# modify keyvals for variables with fold change >= 1
keyvals[which(res$log2FC >= 1 &
                res$p_value < 0.05)] <- "#E50000"
names(keyvals)[which(res$log2FC >= 1 &
                       res$p_value < 0.05)] <- "Up"

# modify keyvals for variables with fold change <= -1
keyvals[which(res$log2FC <= -1 &
                res$p_value <= 0.05)] <- "#3C84FF"
names(keyvals)[which(res$log2FC <= -1 &
                       res$p_value <= 0.05)] <- "Down"

EnhancedVolcano(res,
                x = "log2FC", y = "p_value",
                lab = NA, 
                xlim = c(-12, 12), ylim = c(-0, 5),
                xlab = bquote(~Log[2]~ "Fold Change"),
                ylab = bquote(~-Log[10]~italic(P)),
                axisLabSize = 12,
                title = "Test", subtitle = "",
                titleLabSize = 15
                pCutoff = 0.05, 
                FCcutoff = 1,
                cutoffLineType = "longdash", cutoffLineCol = "black",
                cutoffLineWidth = 1,
                pointSize = c(ifelse(abs(res$log2FC) >= 1 & res$p_value < 0.05, 5, 1)),
                labSize = 6,
                labCol = c("black", "black"),
                labFace = "plain",
                colCustom = keyvals,
                colAlpha = 0.6,
                legend=c("NS", "Log2FC", "pvalue", "pvalue & Log2FC"),
                legendLabels = c('NS', expression(Log[2]~FC),
                                 "p_value", expression(p_value~and~Log[2]~FC)),
                legendPosition = "right",
                legendLabSize = 12, legendIconSize = 12,
                gridlines.major = F, gridlines.minor = F,
                border = "full", borderWidth = 2, borderColour = "black")
ADD REPLYlink modified 22 days ago • written 22 days ago by camillab.10

Hey, sorry, I am only seeing this now. What is the output of:

table(keyvals)

nrow(res)

?

By the way, you should not have to set the value of legend, depending on which version you are using. Which version is it, do you know?

ADD REPLYlink modified 2 days ago • written 2 days ago by Kevin Blighe61k

Great tool! I am trying "Custom shape & colour over-ride" , . i have 4 cell types . can you tell me how to label genes names of different shapes ?

ADD REPLYlink written 3 days ago by archanaverma4330

Hey, did you check the vignette for how you could do this? - https://github.com/kevinblighe/EnhancedVolcano

ADD REPLYlink written 2 days ago by Kevin Blighe61k
Please log in to add an answer.

Help
Access

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.
Powered by Biostar version 2.3.0
Traffic: 1533 users visited in the last hour