5  Violin plots

Violin plots require very little description. They are a depiction of the distribution of a variable. It makes it ideal in order to show differential enrichment patterns alongside different groups. As such, it is also included in Seurat under Seurat::VlnPlot() function. The very first time a new user encounters this function is likely going to be when querying for different QC parameters, such as the number of UMIs, the number of genes or the percentage of mitochondrial RNA. This is how it looks for the number of UMIs:

5.1 Basic usage

p <- Seurat::VlnPlot(sample, 
                     features = "nCount_RNA")
p

Violin plots in Seurat.

The one thing that really stands out here is, indeed, the extra dots that are being plotted alongside the violin plot. Since each dot represent a cell, it quickly becomes the dominant feature of the figure. One can play with the alpha of the dots to reduce their presence:

p <- Seurat::VlnPlot(sample, 
                     features = "nCount_RNA")

# "Surgically" add the alpha parameter in the ggplot2 object.
p$layers[[2]]$aes_params$alpha <- 0.05
p

Remove the dots.

But still, by making the dots almost invisible, we still observe their dominance on the bigger clusters. Therefore, it’s better to remove it. This, together with other modifications are the basis of SCpubr::do_ViolinPlot(). This is how the default plot looks like:

# Basic violin plot.
p <- SCpubr::do_ViolinPlot(sample = sample, 
                           features = "nCount_RNA")
p

Violin plots in SCpubr.

In addition to removing the dots, a boxplot is added to each violin shape, to get a better sense of the quantiles of the distribution. This effect can be removed by using plot_boxplot = FALSE. Also, legend is by default removed, as the groups are being displayed already in the X axis.

# Remove the box plots.
p <- SCpubr::do_ViolinPlot(sample = sample, 
                           features = "nCount_RNA",
                           plot_boxplot = FALSE)
p

Remove the boxplots.

If we want to rotate the X axis labels, we can also do that providing rotate_x_axis_labels with either 0, 45 or 90:

# Rotate x axis labels.
p <- SCpubr::do_ViolinPlot(sample = sample, 
                        features = c("nCount_RNA"),
                        rotate_x_axis_labels = 45)
p

Rotate X axis labels.

5.2 Violin plots as a means of QC

For QC analyses, users might want to also add some other features such as a line indicating where to put the cutoff. This can be achieved by using y_cut parameter. Currently, only one value per plot for y_cut can be used.

# Add horizontal lines.
p <- SCpubr::do_ViolinPlot(sample = sample, 
                           features = "nCount_RNA", 
                           y_cut = 25000)
p

Add horizontal lines.

5.3 Modifying aesthetics

Sometimes we might want to modify the overall look of the violin plots. For instance, the line width of both the violin shape and the box plot can be modified with line_width parameter, which defaults to 1.

# Increase line width.
p1 <- SCpubr::do_ViolinPlot(sample = sample,
                         features = "nCount_RNA")

p2 <- SCpubr::do_ViolinPlot(sample = sample,
                         features = "nCount_RNA",
                         line_width = 2)

p <- p1 / p2
p

Modify the line width.

Also, the width of the box plots can be modified with boxplot_width parameter, which defaults to 0.2. Be aware that this parameter scales the width of the boxplot. This is, if a value of 1 is provided, the box plot will take as much space as the violin shape. It is recommended to deviate from 0.2 by a small amount.

# Decrease boxplot width.
p1 <- SCpubr::do_ViolinPlot(sample = sample,
                            features = "nCount_RNA")

p2 <- SCpubr::do_ViolinPlot(sample = sample,
                            features = "nCount_RNA",
                            boxplot_width = 0.1)

p <- p1 / p2
p

Modify boxplot width.

5.4 Force the same limits on different violin plots.

Finally, we can also set the same range of values for the Y axis using share.y.lims = TRUE. For this, we need to provide multiple features to features parameter. The maximum and minimum values will be the absolute maximum and minimum across the features.

# Share the same Y axis.
p <- SCpubr::do_ViolinPlot(sample = sample,
                           features = c("nCount_RNA", "nFeature_RNA"),
                           ncol = 1,
                           share.y.lims = TRUE)
p

Enforce the same Y axis over multiple violin plots.

5.5 Split by another variable

Finally, we can also generate split violin plots using the split.by parameter. However, plot_boxplot has to be set to FALSE:

# Split violin plots.
sample$orig.ident <- sample(c("A", "B"),
                            ncol(sample),
                            replace = TRUE)

p<- SCpubr::do_ViolinPlot(sample = sample,
                         features = "nCount_RNA",
                         split.by = "orig.ident",
                         plot_boxplot = FALSE,
                         legend.position = "bottom")

p

Generate split violin plots.