Adding Marginal Density Plots to a Graph in R

In this video I demonstrate how to add marginal density plots to your ggplot2 scatterplots in R using two different R packages – ggExtra and ggside. Using these packages I will show you how to add density curves, histograms, boxplots, and violin plots for the marginal distributions and how to divide them by different categories.



Subscribe to stay up to date on my latest videos, courses, and content


library(tidyverse)

## ggExtra #######
library(ggExtra)

# basic scatterplot and marginal distributions 
iris.scatter.1<-ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_point()
iris.scatter.1
ggMarginal(iris.scatter.1)
ggMarginal(iris.scatter.1,type="histogram")
ggMarginal(iris.scatter.1,type="densigram")
ggMarginal(iris.scatter.1,type="boxplot")
ggMarginal(iris.scatter.1,type="violin")

# coloured by species
iris.scatter.2 <- ggplot(iris, aes(Sepal.Length, Sepal.Width, colour = Species)) +
  geom_point() + theme(legend.position="bottom")
iris.scatter.2
ggMarginal(iris.scatter.2, groupColour = TRUE, groupFill = TRUE) 
ggMarginal(iris.scatter.2, groupColour = TRUE, groupFill = TRUE, type="histogram")
ggMarginal(iris.scatter.2, groupColour = TRUE, groupFill = TRUE, type="densigram")
ggMarginal(iris.scatter.2, groupColour = TRUE, groupFill = TRUE, type="boxplot")
ggMarginal(iris.scatter.2, groupColour = TRUE, groupFill = TRUE, type="violin")


## ggside
library(ggside)

# marginal densities
i2 <- iris %>%
  mutate(Species2 = rep(c("A","B"), 75))
p <- ggplot(i2, aes(Sepal.Width, Sepal.Length, color = Species)) +
  geom_point()
p2 <- p + geom_xsidedensity(aes(y=stat(density))) +
  geom_ysidedensity(aes(x=stat(density))) +
  theme_bw()
p2 + labs(title = "No Facets")

# facet across two category combinations
p2 + facet_grid(Species~Species2, space = "free", scale = "free_y") 

# boxplot and density 
ggplot(mpg, aes(displ, hwy, colour = class)) + 
  geom_point(size = 2) +
  geom_xsideboxplot(aes(y =class), orientation = "y") +
  geom_ysidedensity(aes(x = after_stat(density)), position = "stack") +
  theme(ggside.panel.scale = .3) +
  scale_xsidey_discrete() +
  scale_ysidex_continuous(guide = guide_axis(angle = 90), minor_breaks = NULL)