Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding summary information to a density plot created with ggplot

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

like image 984
David LeBauer Avatar asked Dec 27 '10 22:12

David LeBauer


People also ask

How do you fill a density plot in R?

In base R you can use the polygon function to fill the area under the density curve. If you use the rgb function in the col argument instead using a normal color, you can set the transparency of the area of the density plot with the alpha argument, that goes from 0 to all transparency to 1, for a total opaque color.

How do I add a point in ggplot2?

To add an extra point to scatterplot using ggplot2, we can still use geom_point function. We just need to use aes function for quoting with new values for the variables, also we can change the color of this point using colour argument.

Which argument of Ggplot can be used to add customization to plots?

To customize the plot, the following arguments can be used: alpha, color, dotsize and fill. Learn more here: ggplot2 dot plot.


3 Answers

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

like image 200
Prasad Chalasani Avatar answered Oct 23 '22 11:10

Prasad Chalasani


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

like image 37
James Marquez Avatar answered Oct 23 '22 13:10

James Marquez


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) ) )
like image 43
IRTFM Avatar answered Oct 23 '22 11:10

IRTFM