简体   繁体   中英

How to plot two distribution curves in a faceted way in R / ggplot2?

I have two probability distribution curves, a Gamma and a standarized Normal, that I need to compare:

library(ggplot2)

pgammaX <- function(x) pgamma(x, shape = 64.57849, scale = 0.08854802)

f <- ggplot(data.frame(x=c(-4, 9)), aes(x)) + stat_function(fun=pgammaX)
f + stat_function(fun = pnorm)

The output is like this

两条分布曲线

However I need to have the two curves separated by means of the faceting mechanism provided by ggplot2, sharing the Y axis, in a way like shown below:

多面的

I know how to do the faceting if the depicted graphics come from data (ie, from a data.frame), but I don't understand how to do it in a case like this, when the graphics are generated on line by functions. Do you have any idea on this?

you can generate the data similar to what stat_function is doing ahead of time, something like:

x <- seq(-4,9,0.1)
dat <- data.frame(p = c(pnorm(x), pgammaX(x)), g = rep(c(0,1), each = 131), x = rep(x, 2) )
ggplot(dat)+geom_line(aes(x,p, group = g)) + facet_grid(~g)

The issue with doing facet_wrap is that the same stat_function is designed to be applied to each panel of the faceted variable which you don't have.

I would instead plot them separately and use grid.arrange to combine them.

f1 <- ggplot(data.frame(x=c(-4, 9)), aes(x)) + stat_function(fun = pgammaX) + ggtitle("Gamma") + theme(plot.title = element_text(hjust = 0.5))
f2 <- ggplot(data.frame(x=c(-4, 9)), aes(x)) + stat_function(fun = pnorm) + ggtitle("Norm") + theme(plot.title = element_text(hjust = 0.5))
library(gridExtra)
grid.arrange(f1, f2, ncol=2)

Otherwise create the data frame with y values from both pgammaX and pnorm and categorize them under a faceting variable.

Finally I got the answer. First, I need to have two data sets and attach each function to each data set, as follows:

library(ggplot2)

pgammaX <- function(x) pgamma(x, shape = 64.57849, scale = 0.08854802)

a <- data.frame(x=c(3,9), category="Gamma")
b <- data.frame(x=c(-4,4), category="Normal")

f <- ggplot(a, aes(x)) + stat_function(fun=pgammaX) + stat_function(data = b, mapping = aes(x), fun = pnorm)

Then, using facet_wrap(), I separate into two graphics according to the category assigned to each data set, and establishing a free_x scale.

f + facet_wrap("category", scales = "free_x")

The result is shown below:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM