# [R] Plotting a normal curve along with a histogram

#### SlideRule

##### New Member
The R code below is my attempt to plot a histogram and then plot a normal curve for reference. A blue line is drawn to show the mean value. From the example image I've attached you can see that the blue line does not run through the center of the normal curve, as it should; the normal curve appears to be scaled improperly along the x-axes.

I've found many examples on the Internet of how to add normal curves to histograms in R, but none of those examples seem reliable when tested. Can anyone here please give correct R code for this? Thank you.

Code:
# Draw a histogram with a normal curve.
histnorm=function(x, ...)
{
if (length(x)>0)
{
hist(x,freq=FALSE, ...)
rug(x)
curve(dnorm(x, mean=mean(x), sd=sd(x)), add=TRUE, col="red", lty="dotted", xaxt="n")
abline(v=mean(x),col="blue")
mtext(paste("mean ", round(mean(x),1), "; sd ", round(sd(x),1), "; N ", length(x),sep=""), side=1, cex=.75)
} # fi
} # histnorm

#### Dason

Code:
# Draw a histogram with a normal curve.
histnorm=function(x, ...)
{
if (length(x)>0)
{
hist(x,freq=FALSE, ...)
rug(x)
curve(dnorm(x, mean=mean(x), sd=sd(x)), add=TRUE, col="red", lty="dotted", xaxt="n")
abline(v=mean(x),col="blue")
mtext(paste("mean ", round(mean(x),1), "; sd ", round(sd(x),1), "; N ", length(x),sep=""), side=1, cex=.75)
} # fi
} # histnorm
Your problem comes from the fact that you're simultaneously using "x" to represent the data and as a variable inside of curve.

A couple possible fixes: Change the input from "x" to "y" or "data" or something like that and make the corresponding changes in the function
Code:
# Draw a histogram with a normal curve.
histnorm=function(dat, ...)
{
if (length(dat)>0)
{
hist(dat ,freq=FALSE, ...)
rug(dat)
curve(dnorm(x, mean = mean(dat), sd = mean(dat)), add=TRUE, col="red", lty="dotted", xaxt="n")
abline(v=mean(dat),col="blue")
mtext(paste("mean ", round(mean(dat),1), "; sd ", round(sd(dat),1), "; N ", length(dat),sep=""), side=1, cex=.75)
} # fi
} # histnorm
Or you could keep everything the same but you need to remember that the inside of curve considers x to be the variable of interest (not data!) so we can calculate the mean and standard deviation before plugging into curve:

Code:
# Draw a histogram with a normal curve.
histnorm=function(x, ...)
{
if (length(x)>0)
{
hist(x,freq=FALSE, ...)
rug(x)
mn <- mean(x)
stdev <- sd(x)
curve(dnorm(x, mean = mn, sd= stdev), add=TRUE, col="red", lty="dotted", xaxt="n")
abline(v=mean(x),col="blue")
mtext(paste("mean ", round(mean(x),1), "; sd ", round(sd(x),1), "; N ", length(x),sep=""), side=1, cex=.75)
} # fi
} # histnorm

#### SlideRule

##### New Member
Thank you, your second example does seem to work. Can you please explain more about how the values of x are being reassigned in my code? My code doesn't have any explicit reassignment of x, and I don't understand anything in the R 2.12.2 documentation to say that the value of the input arguments to the curve or dnorm functions would be side-affected.