2010-08-16 20 views
84

Uso con frecuencia diagramas de densidad del kernel para ilustrar las distribuciones. Estos son fácil y rápida de crear en I de este modo:Sombreando un gráfico de densidad de kernel entre dos puntos.

set.seed(1) 
draws <- rnorm(100)^2 
dens <- density(draws) 
plot(dens) 
#or in one line like this: plot(density(rnorm(100)^2)) 

que me da este pequeño PDF:

enter image description here

me gustaría dar sombra al área bajo la PDF a partir de los 75 hasta percentiles 95. Es fácil de calcular los puntos usando la función quantile:

q75 <- quantile(draws, .75) 
q95 <- quantile(draws, .95) 

Pero, ¿cómo hacer que la sombra de la zona comprendida entre q75 y q95?

+0

pueden hacerle ejemplo de sombreado de la parte exterior de su rango contra el interior de su rango? Gracias. – Milktrader

Respuesta

67

Con la función polygon(), consulte su página de ayuda y creo que aquí también tenemos preguntas similares.

Necesita encontrar el índice de los valores de los cuantiles para obtener los pares reales (x,y).

Editar: Aquí van:

x1 <- min(which(dens$x >= q75)) 
x2 <- max(which(dens$x < q95)) 
with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray")) 

salida (añadido por JDL)

enter image description here

+3

Nunca hubiera conseguido que funcione si no me has proporcionado la estructura. ¡Gracias! –

+1

Es una de esas cosas ... que han estado en 'demo (gráficos)' desde antes del amanecer a tiempo, así que uno se encuentra de vez en cuando. La misma idea para el sombreado de regresión NBER, etc. –

+1

ohhhh. SABÍA que lo había visto en alguna parte pero que no podía sacar de mi índice mental donde lo había visto. Me alegra que tu índice mental sea mejor que el mío. –

63

Otra solución:

dd <- with(dens,data.frame(x,y)) 
library(ggplot2) 
qplot(x,y,data=dd,geom="line")+ 
    geom_ribbon(data=subset(dd,x>q75 & x<q95),aes(ymax=y),ymin=0, 
       fill="red",colour=NA,alpha=0.5) 

Resultado: alt text

+2

¡eh, eso es fantástico! y lleno de ggplot bondad! –

19

Una solución expandida:

Si quieres sombra ambas colas (copiar & pasta de código de Dirk) y el uso de conocidos los valores x:

set.seed(1) 
draws <- rnorm(100)^2 
dens <- density(draws) 
plot(dens) 

q2  <- 2 
q65 <- 6.5 
qn08 <- -0.8 
qn02 <- -0.2 

x1 <- min(which(dens$x >= q2)) 
x2 <- max(which(dens$x < q65)) 
x3 <- min(which(dens$x >= qn08)) 
x4 <- max(which(dens$x < qn02)) 

with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray")) 
with(dens, polygon(x=c(x[c(x3,x3:x4,x4)]), y= c(0, y[x3:x4], 0), col="gray")) 

Resultado:

2-tailed poly

+0

Tengo el archivo png y lo he alojado en freeimagehosting, y puede que no se esté cargando porque ... No estoy seguro. – Milktrader

+0

Archivo muy borroso.¿Puedes recrearlo y * subirlo aquí directamente * SO tiene su propio servicio de servidores para esto? –

+0

Lo siento, pero no puedo ver cómo subirlo a SO directamente. – Milktrader

17

Esta pregunta necesita una respuesta lattice. Aquí hay uno muy básico, simplemente adaptando el método empleado por Dirk y otros:

#Set up the data 
set.seed(1) 
draws <- rnorm(100)^2 
dens <- density(draws) 

#Put in a simple data frame 
d <- data.frame(x = dens$x, y = dens$y) 

#Define a custom panel function; 
# Options like color don't need to be hard coded  
shadePanel <- function(x,y,shadeLims){ 
    panel.lines(x,y) 
    m1 <- min(which(x >= shadeLims[1])) 
    m2 <- max(which(x <= shadeLims[2])) 
    tmp <- data.frame(x1 = x[c(m1,m1:m2,m2)], y1 = c(0,y[m1:m2],0)) 
    panel.polygon(tmp$x1,tmp$y1,col = "blue") 
} 

#Plot 
xyplot(y~x,data = d, panel = shadePanel, shadeLims = c(1,3)) 

enter image description here

Cuestiones relacionadas