2

This questions somewhat relates to a question I previously posted. However, I have narrowed down exactly what I am trying to do and I feel this question is different enough from my previous question to warrant a new post.

I am adding multiple (>50) curves to a plot in R. Each curve has a corresponding probability (0-1). I have sorted the curves by probability and would like to shade the area under each curve with a transparency alpha weighted by probability.

I am adding the plots in a descending sequence by probability. I would like to shade just the portion under each curve that is not covered by any curves currently on the graph.

I have read many posts on shading areas between curves, or under curves, but I cannot figure out how to shade just the area not covered by any other plot on the graph. I hope this is not considered a duplicate.

  1. Shaded area under two curves using R
  2. Shading a kernel density plot between two points.
  3. How to make gradient color filled
    timeseries plot in R
  4. Shading between curves in R

Here is an example picture (marked up in MS paint) of what I would like a final plot to look like (except without the lines inside the polygons). I used four curves in this example, but I will be adding many more when I figure this out. I added the curve with the highest response first, then each subsequent curve, shading just the portion not already filled.

enter image description here

In the above example I used lines to add the curves to the graph and then shaded them in MS paint. I understand to fill in the area under each curve I will need to use polygon with border=NA .Here is an example of how I am planning on using polygon to shade based on the response value. My current approach is to adjust the color using alpha, but if there is a more practical approach using a gray scale pallet or gradient I am open to suggestions.

polygon(x, y1,col=rgb(0,0,0,alpha=(1-wei.param[1,3])), border=NA )

I have tried several different approaches (based on the above hyperlinks) to specify the dimensions of each polygon. I can get it to work for polygons 1-3, but after that they start stacking on top of each other.

Here are example data and code to reproduce the plots.

diameters<-c(rep(1.5,393),3,3,3,3,3.1,3.1,3.1,3.2,3.2,3.2,3.3,3.4,3.4,3.4,3.4,3.4,
            3.4,3.4,3.4,3.5,3.5,3.6,3.6,3.7,3.7,3.7,3.7,3.8,3.8,3.8,3.8,3.8,3.8,
            3.9,3.9,4,4,4,4.1,4.2,4.2,4.2,4.2,4.3,4.3,4.4,4.49,4.5,4.5,4.6,4.7,
            4.7,4.7,4.8,4.9,4.9,4.9,5,5,5,5,5.1,5.1,5.2,5.3,5.4,5.4,5.6,5.7,5.7,
            5.7,5.8,6,6,6,6.3,6.4,6.6,6.9,6.9,6.9,7,7.1,7.2,7.4,7.4,7.7,7.8,7.9,
            7.9,8.2,8.5,8.5,8.9,9.2,10.2,10.47,10.5,10.7,11.7,13.2,13.5,14.4,14.5,
            14.5,15.1,18.4)

wei.param<-matrix(data=NA,nrow=5,ncol=3,dimnames = list(c(),c("shape", "scale", "prob")))
wei.param[,1]<-c(1.834682,2.720390,3.073429,1.9,1.9)
wei.param[,2]<-c(2.78,2.78,2.78,1.6,2.8710692)
wei.param[,3]<-c(0.49, 0.46, 0.26, 0.26, 0.07)

x=seq(0,20,1)
y1<-dweibull(x,shape=wei.param[1,1],scale=wei.param[1,2])
y2<-dweibull(x,shape=wei.param[2,1],scale=wei.param[2,2])
y3<-dweibull(x,shape=wei.param[3,1],scale=wei.param[3,2])
y4<-dweibull(x,shape=wei.param[4,1],scale=wei.param[4,2])

#Plot
hist(diameters,freq=F,main='',ylim=c(0,.5))

polygon(x, y1,col=rgb(0,0,0,alpha=(1-wei.param[1,3])), border=NA )

lines(x, y1)
lines(x, y2)
lines(x, y3)
lines(x, y4)
Community
  • 1
  • 1
GNG
  • 239
  • 2
  • 11
  • 1
    if you just remove the transparency, isn't that what you want? – rawr Apr 10 '15 at 02:04
  • @GNG The trick is to add a white polygon behind your color polygons. Also, as a long term programing goal, I would suggest learning `ggplot'. – Richard Erickson Apr 10 '15 at 02:46
  • Also, @GNG, good job with a reproducible question! – Richard Erickson Apr 10 '15 at 03:07
  • 1
    @RichardErickson It seems 'ggplot' is the solution to many graphical questions I search for. I need to stop dragging my feet and become familiar with it. Thanks, sometimes I don't know exactly what I want to ask, but I figure if I show what I've read and give a good example experts our there can understand what I am trying to do. I appreciate your help; I will give it a run through then accept your answer. – GNG Apr 10 '15 at 03:32

1 Answers1

2

I think this what you want:

enter image description here

I don't know how to do this with base R graphics, but here's the code for ggplot2, which I know better. Note that ggplot2 requires data to be input as a data.frame. Also, I created a second probability column so that I could group the polygons with ggplot2.

df <- data.frame(x = rep(x, 4), y = c(y1, y2, y3, y4), 
                Prob = c(
                rep(wei.param[1,3], length(y1)),
                rep(wei.param[2,3], length(y2)),
                rep(wei.param[2,3], length(y2)),
                rep(wei.param[4,3], length(y4))))

df$Prob2 = as.factor(df$Prob)
library(scales) # needed for alpha function with ggplot2
library(ggplot2)

example <- ggplot() +
    geom_histogram(aes(x = diameters, y = ..density..), 
                prob = TRUE, fill = alpha('white', 0), color = 'black') +
    geom_polygon(data = df, aes( x = x, y = y), color = 'white', 
                 fill = 'white') +
    geom_polygon(data = df, aes( x = x, y = y, alpha = Prob, 
                 group = Prob2)) +
    geom_polygon() + theme_bw()
ggsave('example.jpg', example, width = 6, height = 4)

You should be able to do a similar trick with base R. All you need to do is plot the white polygons over your histogram, but under your shaded polygons. If you decide to use my ggplot2 code you'll probably want to tweak bin width (see ?geom_histogram for details about how to do this).

Richard Erickson
  • 2,568
  • 8
  • 26
  • 39