9

I have a density plot and I would like to add some summary information such as placing a line at the median and shading the 90% credible intervals (5th and 95th quantiles). Is there a way to do this in ggplot?

This is the type of plot that I would like to summarize:

I can figure out how to draw a line from the y=0 to y= density(median(x)), but it is not clear to me if I can shade the plot with a 90% CI. Alternatively, I could add a horizontal boxplot above the density plot, but it is not clear how to rotate the boxplot by itself, without rotating the density plot along with it.

x <- as.vector(rnorm(10000))
d <- as.data.frame(x=x)
library(ggplot2)
ggplot(data = d) + theme_bw() + 
  geom_density(aes(x=x, y = ..density..), color = 'black')

alt text

3 Answers 3

18

You can use the geom_area() function. First make the density explicit using the density() function.

x <- as.vector(rnorm(10000))
d <- as.data.frame(x=x)
library(ggplot2)
p <- ggplot(data = d) + theme_bw() + 
  geom_density(aes(x=x, y = ..density..), color = 'black')
# new code is below
q5 <- quantile(x,.05)
q95 <- quantile(x,.95)
medx <- median(x)
x.dens <- density(x)
df.dens <- data.frame(x = x.dens$x, y = x.dens$y)
p + geom_area(data = subset(df.dens, x >= q5 & x <= q95), 
              aes(x=x,y=y), fill = 'blue') +
    geom_vline(xintercept = medx)

alt text

Sign up to request clarification or add additional context in comments.

6 Comments

@pchalansani thanks for showing me this. that is exactly what I was hoping to do... now I just need to get the median line in there. I've been trying to use geom_vline but that doesn't seem to work.
@David I updated it with the median line, not sure why geom_vline wasn't working for you
@pchalansani thanks for helping me move forward with this. looks nice.
@pchalansani thanks for the update, but I am having the trouble that geom_vline places the line at x=0 instead of at the median. If you transform x, x <- x+10, you will see the density moves but the line doesn't...
@David I looked at the geom_vline help page, and it seems you need to use xintercept... that works, I fixed the code... had.co.nz/ggplot2/geom_vline.html
|
7

I wanted to add to @Prasad Chalasani's answer for those like myself that came looking to add all 3 Std areas. 1 Std is the darkest shade, 2 Std is the middle shade, and 3 Std is the lightest shade. The mean is the black line and the median is the white line.

set.seed(501) # Make random sample reproducible
x <- as.vector(rnorm(100))
d <- as.data.frame(x=x)
library(ggplot2)

p <- ggplot(data=d) +
     theme_bw() + 
     geom_density(aes(x=x, y = ..density..), color = '#619CFF')

# new code is below
q15.9 <- quantile(x, .159) # 1 Std 68.2%
q84.1 <- quantile(x, .841)
q2.3  <- quantile(x, .023) # 2 Std 95.4%
q97.7 <- quantile(x, .977)
q0.01 <- quantile(x, .001) # 3 Std 99.8%
q99.9 <- quantile(x, .999)
meanx <- mean(x)
medx  <- median(x)
x.dens  <- density(x)
df.dens <- data.frame(x=x.dens$x, y=x.dens$y)

p + geom_area(data = subset(df.dens, x >= q15.9 & x <= q84.1), # 1 Std 68.2%
              aes(x=x,y=y), fill='#619CFF', alpha=0.8) +
    geom_area(data = subset(df.dens, x >= q2.3 & x <= q97.7), # 2 Std 95.4%
              aes(x=x,y=y), fill='#619CFF', alpha=0.6) +
    geom_area(data = subset(df.dens, x >= q0.01 & x <= q99.9), # 3 Std 99.8%
              aes(x=x,y=y), fill='#619CFF', alpha=0.3) +
    geom_vline(xintercept=meanx) +
    geom_vline(xintercept=medx, color='#FFFFFF')

enter image description here

Comments

3

This (also) does the vertical line at the median:

ggplot(data = d) + theme_bw() + 
   geom_density(aes(x=x, y = ..density..), color = 'black') + 
   geom_line(aes(x=median(x), y=c(0,.4) ) )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.