[R] Overlying a Normal Dist in a Barplot
Marc Schwartz
MSchwartz at mn.rr.com
Sat Jul 9 04:38:23 CEST 2005
On Fri, 2005-07-08 at 21:58 -0400, Gabor Grothendieck wrote:
> On 7/8/05, Bret Collier <bret at tamu.edu> wrote:
> > R-Users,
> > Hopefully someone can shed some light on these questions as I had
> > little luck searching the archives (although I probably missed something
> > in my search due to the search phrase). I estimated multinomial
> > probabilities for some count data (number successful offspring) ranging
> > from 0 to 8 (9 possible response categories). I constructed a barplot
> > (using barplot2) and I want to "overlay" a normal distribution on the
> > figure (using rnorm (1000, mean, sd)). My intent is to show that using
> > a mean(and associated sd) estimated from discrete count data may not be
> > a valid representation of the distribution of successful offspring.
> >
> > Obviously the x and y axes (as structured in barplot2) will not be
> > equivalent for these 2 sets of information and this shows up in my
> > example below.
> >
> > 1) Is it possible to somehow reconcile the underlying x-axis to the
> > same scale as would be needed to overly the normal distribution (e.g.
> > where 2.5 would fall on the normal density, I could relate it to 2.5 on
> > the barplot)? Then, using axis (side=4) I assume I could insert a
> > y-axis for the normal distribution.
> >
> > 2) Is lines(density(x)) the appropriate way to insert a normal
> > distribution into this type of figure? Should I use 'curve'?
> >
> > If someone could point me in the right direction, I would appreciate
> > it.
> >
> > TIA, Bret
> >
> > Example:
> >
> > testdata
> > 0 0.196454948
> > 1 0.063515510
> > 2 0.149187592
> > 3 0.237813885
> > 4 0.282127031
> > 5 0.066469719
> > 6 0.001477105
> > 7 0.001477105
> > 8 0.001477105
> >
> >
> > x<-rnorm(1000, 2.84, 1.57)
> > barplot2(testdata, xlab="Fledgling Number",
> > ylab="Probability", ylim=c(0, 1), col="black",
> > border="black", axis.lty=1)
> > lines(density(x))
> >
>
> Maybe something like this using rect and curve:
>
> # data from your post
> testdata <- c(0.196454948, 0.06351551, 0.149187592, 0.237813885,
> 0.282127031, 0.066469719, 0.001477105, 0.001477105, 0.001477105)
> x <- 0:9
>
> # setup plot ranges noting max of normal density is at mean
> xrange <- range(x) + c(-0.5,+0.5)
> yrange <- range(c(testdata, dnorm(2.84, 2.84, 1.57), 0))
> plot(xrange, yrange, type = "n", xlab = "X", ylab = "Probability", xaxt = "n")
> axis(1, x)
>
> # draw bars using rect and density using curve
> rect(x - 0.5, 0, x + 0.5, testdata, col = "lightgrey")
> curve(dnorm(x, 2.84, 1.57), min(xrange), max(xrange), add = TRUE)
Nice solution Gabor.
I had to think about this one for a bit, and think I may have it using
barplot[2]():
> testdata
V1 V2
1 0 0.196454948
2 1 0.063515510
3 2 0.149187592
4 3 0.237813885
5 4 0.282127031
6 5 0.066469719
7 6 0.001477105
8 7 0.001477105
9 8 0.001477105
# Change 'space = 0' so that bars are adjacent to each other
# This also puts each bar center at seq(0.5, 8.5, 1)
mp <- barplot2(testdata[, 2], xlab="Fledgling Number",
ylab="Probability", ylim=c(0, .3),
axis.lty = 1, names.arg = testdata[, 1],
space = 0)
> mp
[,1]
[1,] 0.5
[2,] 1.5
[3,] 2.5
[4,] 3.5
[5,] 4.5
[6,] 5.5
[7,] 6.5
[8,] 7.5
[9,] 8.5
x <- testdata[, 1]
# Now do the curve and shift the mean by +0.5
# To coincide with the bar centers
curve(dnorm(x, 2.84 + 0.5, 1.57), add = TRUE)
I think that does it.
HTH,
Marc Schwartz
More information about the R-help
mailing list