1

How can you add normal marginal distributions to a plot in R?

Here is an example code and I would like to have normal marginals added to the sides (top and right side):

x<- rweibull(100, 2.6, 3)
y<- rweibull(100, 1.8, 3)
xy.df<- data.frame(cbind(x,y))
p1<- ggplot(xy.df, aes(x,y)) +
  geom_point(colour = "blue", size = 0.25) +
  geom_density2d() +
  theme_classic() +
    border()
ggMarginal(p1, type="density")
EM823823
  • 121
  • 5

2 Answers2

1

If you mean a theoretical normal density, you can do that with the cowplot package:

library(ggplot2)
library(cowplot)

x <- 1:30
y <- x + rnorm(30, 0, 1)
dat <- data.frame(x = x, y = y)

gg <- ggplot(dat) + geom_point(aes(x = x, y = y))

y_density <- axis_canvas(gg, axis = "y", coord_flip = TRUE) +
  geom_function(fun = dnorm, args = list(mean = 15, sd = 5)) +
  coord_flip()

# create the combined plot
combined_plot <- insert_yaxis_grob(gg, y_density, position = "right")

# show the result
ggdraw(combined_plot)

enter image description here

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • The answer is close to what I need, and that's because I wasn't clear enough. I apologize for that! I would like to add the theoretical normal distribution along with the empirical distribution. So each side, right and top, should have two density plots: a theoretical normal and an empirical distribution. – EM823823 Dec 30 '21 at 00:57
1

This may be a bit late, but you can accomplish what you want from the ggside package. You will need to use the dev version from the github to use the the full functionality though.

Currently, the CRAN version of ggside does not have (x|y)side variants to stat_function(), but the current dev branch has a version working.

Here we plot the normal density estimates filled in with blue, and then the theoretical distribution is colored red.

library(ggplot2)
library(ggside)
#> Registered S3 method overwritten by 'ggside':
#>   method from   
#>   +.gg   ggplot2
x<- rweibull(100, 2.6, 3)
y<- rweibull(100, 1.8, 3)
xy.df<- data.frame(cbind(x,y))
p <- ggplot(xy.df, aes(x, y)) +
  geom_point(colour = "blue", size = 0.25) +
  geom_density2d() +
  geom_xsidedensity(fill = "blue", alpha = .3) +
  geom_ysidedensity(fill = "blue", alpha = .3) +
  stat_xsidefunction(fun = dweibull, args = list(shape = 1.8, scale = 3), colour = "red") +
  stat_ysidefunction(fun = dweibull, args = list(shape = 2.6, scale = 3), colour = "red") +
  theme_classic() 
p

Created on 2022-02-01 by the reprex package (v2.0.1)

Justin Landis
  • 1,981
  • 7
  • 9