2014-11-28 12 views
9

Supponiamo ad es. Voglio ombreggiare l'area sotto la curva di densità per la distribuzione normale standard per decile. Voglio che il 10% più a sinistra dell'area abbia un'ombra diversa per il 10% successivo e così via.Area ombreggiata (riempimento o colore) sotto la curva di densità di quantile

Si tratta di una variante per le domande "Shading a kernel density plot between two points" e "ggplot2 shade area under density curve by group", ma voglio ombra ogni quantile (nel mio esempio, ogni gruppo è un decile ma il processo dovrebbe facilmente generalizzare ad altri quantili).

Non mi importa se una soluzione utilizza la grafica ggplot2 o base e se questa viene eseguita direttamente da una formula (che sarebbe davvero accurata) o basata sulla creazione di un frame di dati prima. In quest'ultimo caso, si consiglia:

delta <- 0.0001 
z.df <- data.frame(x = seq(from=-3, to=3, by=delta)) 
z.df$pdf <- dnorm(z.df$x) 
z.df$decile <- floor(10*pnorm(z.df$x) + 1) 

nota che la soluzione ingenua ggplot(z.df, aes(x = x, fill = quantile)) + geom_ribbon(aes(ymin = 0, ymax = pdf)) fallirebbe perché Aesthetics can not vary with a ribbon.

risposta

9

realtà estetica può variare con geom_ribbon(...) (o geom_area(...), che è fondamentalmente la stessa cosa), fino a quando si imposta la group estetica pure.

delta  <- 0.001 
quantiles <- 10 
z.df  <- data.frame(x = seq(from=-3, to=3, by=delta)) 
z.df$pdf <- dnorm(z.df$x) 
z.df$qt <- cut(pnorm(z.df$x),breaks=quantiles,labels=F) 

library(ggplot2) 
ggplot(z.df,aes(x=x,y=pdf))+ 
    geom_area(aes(x=x,y=pdf,group=qt,fill=qt),color="black")+ 
    scale_fill_gradient2(midpoint=median(unique(z.df$qt)), guide="none") + 
    theme_bw() 

Impostazione quantiles <- 20 all'inizio produce questo:

+0

Questo è veramente bello. "L'estetica non può variare con un nastro" è uno dei messaggi di errore più informativi che ho avuto da ggplot, un peccato che fosse fuorviante! – Silverfish

3

qualcosa che funziona e potrebbe generalizzare:

require(ggplot2) 
g <- ggplot(z.df, aes(x=x, y=pdf, fill=decile)) + 
    scale_fill_gradient2(midpoint=5.5, guide="none") + 
    theme_bw() 
for(n in 1:10) { 
    g <- g + geom_ribbon(data=z.df[z.df$decile == n,], aes(ymin=0, ymax=pdf), colour = "black") 
} 
print(g) 

io non trovare questo particolarmente soddisfacente dal momento che (1) devo aggiungere un nastro per ogni decile, e (2) se sto usando un for loop in R Di solito sto facendo qualcosa di sbagliato.

Ma la trama che dà è ragionevole:

Normal distribution curve with shaded deciles

Problemi correlati