[R] Selectively shading areas under two density curves
Jim Lemon
jim at bitwrit.com.au
Mon Aug 6 12:56:15 CEST 2007
Ian Watson wrote:
> Dear Listers,
>
> I am drawing a plot of two density curves, for male and female incomes. I would
> like to shade/hatch/color (whatever) the areas under the curves which are
> distinctive for each gender. This is the code I have tried so far:
>
>
> m <- density(topmal.d$y, bw = "sj")
> f <- density(topfem.d$y, bw = "sj")
> par(mfrow = c(1,1))
> plot(x = c(0,400), y = c(0,0.02), type = "n",
> bty = "l", xlab = "Annual earnings (in $thousands)", ylab = "Density")
> polygon(m, col = "blue", border = "blue", density = 20, angle = -45)
> polygon(f, col = "red", border = "red", density = 20, angle = 45)
>
>
> Without the data I realise you may not be able to see my goal. But basically the
> m density and the f density overlap for most of the plot, but areas "bulge"
> out on the left and right of the overlapped area. What I'm wanting to do is
> shade/hatch/color etc these areas which are unique to each density, that is,
> which are outside the overlapped area.
>
> My code is successful at hatching the bulging areas, but leaves me with a double
> hatched area for the overlap, which is distracting. If I could turn this double
> hatched area white, that would achieve my goal, though ideally I would like to
> be able to specify something like "shade only areas under the m density curve
> which are not also under the f density curve (and shade only under the f density
> curve those areas not under the m density curve".
>
Hi Ian,
Once you get used to the vagaries of "density" output, this isn't too
hard, as you only have one crossing. I think this gets you what you want:
minc<-rnorm(1000,mean=65000,sd=15000)
finc<-rnorm(1000,mean=55000,sd=15000)
m <- density(minc, bw = "sj")
f <- density(finc, bw = "sj")
plot(m$x,m$y,main="Male vs female income distribution",
xlab="",ylab="Density",type="l",xaxt="n")
library(plotrix)
axis.mult(1,at=c(0,20000,40000,60000,80000,100000,120000),mult=1000,
labels=c("0","20","40","60","80","100","120"),mult.label="Annual
income/1000")
lines(f$x,f$y)
fontop.end<-max(which(f$y>m$y))
xend<-length(f$x)
polygon(c(f$x[1:fontop.end],rev(m$x[1:fontop.end])),
c(f$y[1:fontop.end],rev(m$y[1:fontop.end])),col="red")
fontop.end<-fontop.end+1
polygon(c(f$x[fontop.end:xend],rev(m$x[fontop.end:xend])),
c(f$y[fontop.end:xend],rev(m$y[fontop.end:xend])),col="blue")
Jim
More information about the R-help
mailing list