2016-05-15 27 views
14

Sto provando a tracciare una distribuzione CDF utilizzando R e ggplot2. Tuttavia, sto riscontrando difficoltà nel tracciare la funzione CDF dopo aver trasformato l'asse Y per ottenere una linea retta. Questo tipo di trama viene spesso utilizzato nei grafici di carta di Gumbel, ma qui userò come esempio la distribuzione normale.La trasformazione della scala ggplot agisce diversamente su punti e funzioni

I genera i dati e traccia la funzione di densità cumulativa dei dati insieme alla funzione. Si adattano bene. Tuttavia, quando applico una trasformazione dell'asse Y, non si adattano più.

sim <- rnorm(100) #Simulate some data 
sim <- sort(sim) #Sort it 

cdf <- seq(0,1,length.out=length(sim)) #Compute data CDF 

df <- data.frame(x=sim, y=cdf) #Build data.frame 

library(scales) 
library(ggplot2) 

#Now plot! 
gg <- ggplot(df, aes(x=x, y=y)) + 
     geom_point() + 
     stat_function(fun = pnorm, colour="red") 
gg 

E l'uscita dovrebbe essere qualcosa sulle linee di: enter image description here Buono!

Ora provo a trasformare l'asse Y in base alla distribuzione utilizzata.

#Apply transformation 
gg + scale_y_continuous(trans=probability_trans("norm")) 

e il risultato è: enter image description here

I punti si trasformano in modo corretto (giacciono su una linea retta), ma la funzione non è!

Tuttavia, tutto sembra funzionare bene se lo faccio in questo modo, il calcolo del CDF con ggplot:

ggplot(data.frame(x=sim), aes(x=x)) + 
    stat_ecdf(geom = "point") + 
    stat_function(fun="pnorm", colour="red") + 
    scale_y_continuous(trans=probability_trans("norm")) 

Il risultato è OK: This wokrs OK

Perché succede questo? Perché il calcolo del CDF non funziona manualmente con le trasformazioni di scala?

risposta

8

Questo funziona:

gg <- ggplot(df, aes(x=x, y=y)) + 
    geom_point() + 
    stat_function(fun ="pnorm", colour="red", inherit.aes = FALSE) + 
    scale_y_continuous(trans=probability_trans("norm")) 
gg 

enter image description here

Possibile spiegazione:

documentazione afferma: inherit.aes Se FALSE, ignora l'estetica di default, piuttosto che unire con loro . Questo è molto utile per le funzioni di supporto che definiscono sia i dati che l'estetica e non dovrebbero ereditare il comportamento dalla specifica di trama predefinita, ad es. frontiere.

mia ipotesi: Come scale_y_continuous cambia l'estetica della trama principale, abbiamo bisogno di spegnere il default inherit.aes=TRUE. Sembra che inherit.aes=TRUE in stat_function preleva la sua estetica dal primo strato della trama, e quindi la trasformazione della scala non ha alcun impatto se non specificamente scelto.

+0

Grazie. Hai un'ipotesi sul perché usare 'geom_ecdf()' funziona anche senza 'inherit.aes'? – AF7

+1

'stat_ecdf' non ha una struttura di ereditarietà estetica, l'unica opzione è sovrascrivere l'estetica del layer sovrascrivendo quello stesso livello. 'stat_function' d'altra parte _superimuove_ una funzione sul livello di trama, e' inherit.aes = TRUE' (il valore predefinito) seleziona i mapping estetici dal livello superiore del grafico. Ciò che mi ha dato il vero problema era il _superimpose_ in 'stat_function'.Mi sembra che 'stat_function' è stato progettato per seguire le mappature della trama reale che si costruisce (strato superiore) senza essere influenzato da tutte le modifiche del livello inferiore ai mapping estetici. – Divi