Violin plot with data points in ggplot2

Sample data

The following data set contains the effect of vitamin C on Tooth Growth. The dose column has been converted into a factor to be used as the categorical variable.

# Sample data set
df <- ToothGrowth
df$dose <- as.factor(df$dose)

Adding jittered points

Option 1

The points can be added over a violin plot with geom_point. However, it is recommended to add some jitter with position_jitter, where seed is the pseurodandom number generator seed (optional) and width is the jittering width.

# install.packages("ggplot2")
library(ggplot2)

ggplot(df, aes(x = dose, y = len, fill = dose)) +
  geom_violin(alpha = 0.5) +
  geom_point(position = position_jitter(seed = 1, width = 0.2)) +
  theme(legend.position = "none")

ggplot2 violin plot with data points

Option 2

You can get the same result using geom_jitter function.

# install.packages("ggplot2")
library(ggplot2)

ggplot(df, aes(x = dose, y = len, fill = dose)) +
  geom_violin(alpha = 0.5) +
  geom_jitter(position = position_jitter(seed = 1, width = 0.2)) +
  theme(legend.position = "none")

Violin plot with observations in ggplot2

Adding a dot plot

Violin plot with dots in ggplot2

If you want to create a violin plot with dots in ggplot2 you can use geom_dotplot, setting binaxis = "y" and stackdir = "center". Note that dotsize controls the size of the points.

# install.packages("ggplot2")
library(ggplot2)

ggplot(df, aes(x = dose, y = len, fill = dose)) +
  geom_violin(alpha = 0.5) +
  geom_dotplot(binaxis = "y",
               stackdir = "center",
               dotsize = 0.5) +
  theme(legend.position = "none")

ggplot violin plot with dots

The default dots are of the same color of the groups. To override this you can specify a fill color inside geom_dotplot.

# install.packages("ggplot2")
library(ggplot2)

ggplot(df, aes(x = dose, y = len, fill = dose)) +
  geom_violin(alpha = 0.5) +
  geom_dotplot(binaxis= "y",
               stackdir = "center",
               dotsize = 0.5,
               fill = 1) +
  theme(legend.position = "none")

Adding a beeswarm

An alternative for adding data points over a violin plot in ggplot is using the geom_beeswarm function from ggbeeswarm library.

# install.packages("ggplot2")
# install.packages("ggbeeswarm")
library(ggplot2)
library(ggbeeswarm)

ggplot(df, aes(x = dose, y = len, fill = dose)) +
  geom_violin(alpha = 0.5) +
  geom_beeswarm() +
  theme(legend.position = "none")

Violin plot and beeswarm in ggplot2

The ggbeeswarm package also contains a function named geom_quasirandom, which can be used to add the points inside the violins, as you can see in the example below.

# install.packages("ggplot2")
# install.packages("ggbeeswarm")
library(ggplot2)
library(ggbeeswarm)

ggplot(df, aes(x = dose, y = len, fill = dose)) +
  geom_violin(alpha = 0.5) +
  geom_quasirandom() +
  theme(legend.position = "none")

Violin plot with data points inside the violin in R ggplot2

Data Sketches

A journey of imagination, exploration, and beautiful data visualizations

Buy on Amazon
Better Data Visualizations

A Guide for Scholars, Researchers, and Wonks

Buy on Amazon
Storytelling with Data

A Data Visualization Guide for Business Professionals

Buy on Amazon

See also