# Re: [R] Overlying a Normal Dist in a Barplot

From: Marc Schwartz <MSchwartz_at_mn.rr.com>
Date: Sat 09 Jul 2005 - 12:38:23 EST

On Fri, 2005-07-08 at 21:58 -0400, Gabor Grothendieck wrote:
> On 7/8/05, Bret Collier <bret@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.

> 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

R-help@stat.math.ethz.ch mailing list