Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to plot multiple normal distributions in 1 figure in R

Tags:

plot

r

I have a data that gives the mean and SD:

#info mean sd
info1 20.84 4.56
info2 29.18 5.41
info3 38.90 6.22

Actually there are more than 100 lines of this. How can I plot normal distributions for each one of the line in one figure given the above data?

like image 646
neversaint Avatar asked Dec 10 '22 00:12

neversaint


2 Answers

Depending on how large N truly gets, you may want to split this up over a set of multiple charts. But, here's the basic approach. First, you need to generate some random data according to your mean and sd. I chose 1000 random points, you can adjust as necessary. Next, set up a blank plot with the appropriate dimensions, then use lines and density to add the data. I used a for loop because it provided a nice way to specify the linetype for each data point. Finally, add a legend at the end:

dat <- read.table(text = "info mean sd
info1 20.84 4.56
info2 29.18 5.41
info3 38.90 6.22
", header = TRUE)

densities <- apply(dat[, -1], 1, function(x) rnorm(n = 1000, mean = x[1], sd = x[2]))
colnames(densities) <- dat$info

plot(0, type = "n", xlim = c(min(densities), max(densities)), ylim = c(0, .2))
for (d in 1:ncol(densities)){
  lines(density(densities[, d]), lty = d)
}
legend("topright", legend=colnames(densities), lty=1:ncol(densities))

enter image description here

Or, use ggplot2 which can have lots of benefits, namely it will specify reasonable xlim and ylim values for you automagically, and do sensible things with the legend without much fuss.

library(reshape2)
library(ggplot2)
#Put into long format
densities.m <- melt(densities)
#Plot
ggplot(densities.m, aes(value, linetype = Var2)) + geom_density()

enter image description here

like image 129
Chase Avatar answered Jan 18 '23 11:01

Chase


Again a dollar short and a day late. Chase has a very thorough response. Here's my crack at it:

dat <- read.table(text="info  mean  sd
info1 20.84 4.56
info2 29.18 5.41
info3 38.90 6.22", header=T)

dat <- transform(dat, lower= mean-3*sd, upper= mean+3*sd)

plot(x=c(min(dat$lower)-2, max(dat$upper)+2), y=c(0, .25), ylab="", 
    xlim=c(min(dat$lower)-2, max(dat$upper)+2), xlab="", 
    axes=FALSE, xaxs = "i", type="n")
box()

FUN <- function(rownum) {
    par(new=TRUE)
    curve(dnorm(x,dat[rownum, 2], dat[rownum, 3]),
        xlim=c(c(min(dat$lower)-2, max(dat$upper)+2)), 
        ylim=c(0, .22),
        ylab="", xlab="")
}

lapply(seq_len(nrow(dat)), function(i) FUN(i))

enter image description here

like image 31
Tyler Rinker Avatar answered Jan 18 '23 12:01

Tyler Rinker