0

I'm wondering how to fully cover a cylindrical area between two curves using some color? Right now, I've tried using rect() but there remain two tiny white spaces above and below the rect() that I don't know how to cover?

Here is my current R code:

curve(dnorm(x), -1.96, 1.96, bty="n", ann=F, axes=F, xaxs="i", yaxs="i")
curve(-dnorm(x), -1.96, 1.96, add=TRUE)

rect(-.5, -dnorm(-.5), .5, dnorm(.5), col="red" )  # How can I fill-up the white space 
                                                   # above and below the rectangle?
axis(1, at=c(-1.96,0,1.96),mgp=c(2, .6, .45), tcl=F )

Also, Here is a picture showing the top white space and the bottom white space:

enter image description here

rawr
  • 20,481
  • 4
  • 44
  • 78
rnorouzian
  • 7,397
  • 5
  • 27
  • 72
  • What spaces are you talking about? Can you add an image to make it more clear? – MrFlick Feb 21 '17 at 04:52
  • 1
    Whoa, your code is not producing that at all. Is there something you're not telling us? (My answer still applies in concept, though you'll need to adjust it for your mirroring.) – r2evans Feb 21 '17 at 04:57
  • Have you looked at other answers about filling areas under curves? http://stackoverflow.com/questions/3494593/shading-a-kernel-density-plot-between-two-points – MrFlick Feb 21 '17 at 04:59

2 Answers2

2

The line at the bottom is fixable by adding line=0 to axis(). (I find the documentation at ?axis to imply that the default line=NA will place the line at the margin vice "number of lines into the margin".

Perhaps I'm misunderstanding you, but you cannot fill the top white space with a rectangle. TO follow the curvature at the top of the curve, you need polygon:

curve(dnorm(x), -1.96, 1.96, bty="n", ann=F, axes=F, xaxs="i", yaxs="i")
curve(-dnorm(x), -1.96, 1.96, add=TRUE)
n <- 50
xs <- seq(-0.5, 0.5, len=n)
polygon(c(xs[1], xs, xs[n]), c(0, dnorm(xs), 0), col='red')
axis(1, at=c(-1.96,0,1.96),mgp=c(2, .6, .45), tcl=F , line = 0)

normal curve

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • I thought the single function call would be self-evident, but I'm using *your code* to start this plot. Take a look at [`?polygon`](https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/polygon.html) for further explanation. – r2evans Feb 21 '17 at 04:59
  • No, you can do it one. Just think of a `polygon` as a call to `lines` that wraps-around to the starting point and optionally colors the inner space. There are plenty of examples on SO (as well as the examples within `?polygon` that clearly exhaust the options). – r2evans Feb 21 '17 at 05:13
  • StackOverflow, you might have heard of it ;-) – r2evans Feb 21 '17 at 05:36
0

With ggplot:

library(ggplot2)
ggplot(data.frame(x=seq(-1.96,1.96,0.01)), aes(x)) + 
  stat_function(fun=dnorm, xlim=c(-1.96, 1.96))+
  stat_function(fun=function(x)-dnorm(x), xlim=c(-1.96, 1.96))+
  geom_rect(aes(xmin=-.5, xmax=.5,ymin=-dnorm(.5), ymax=dnorm(.5)), fill='red', col='black', alpha=0.5) +
  geom_hline(yintercept=0) +
  geom_text(data=data.frame(x=c(0.00,-1.96,1.96), y=rep(0,3)), aes(x=x, y=y, label = x), nudge_y = 0.015) +
  theme_bw()

enter image description here

Sandipan Dey
  • 21,482
  • 2
  • 51
  • 63