2009-12-26 17 views
7

Mi sono imbattuto in una serie di situazioni in cui voglio tracciare più punti di quelli che dovrei essere - il principale ostacolo è che quando condivido i miei complotti con le persone o li incorporo in documenti, occupano troppo spazio. È molto semplice campionare casualmente le righe in un dataframe.punti di trama massima in R?

se voglio un campione realmente casuale per una trama punto, è facile dire:

ggplot(x,y,data=myDf[sample(1:nrow(myDf),1000),]) 

Tuttavia, mi chiedevo se ci fossero più efficaci (idealmente in scatola) modi per specificare il numero di punti della trama in modo tale che i tuoi dati effettivi si riflettano accuratamente nella trama. Quindi ecco un esempio. Supponiamo di tracciare qualcosa come il CCDF di una distribuzione a coda pesante, ad es.

ccdf <- function(myList,density=FALSE) 
{ 
    # generates the CCDF of a list or vector 
    freqs = table(myList) 
    X = rev(as.numeric(names(freqs))) 
    Y =cumsum(rev(as.list(freqs))); 
    data.frame(x=X,count=Y) 
} 
qplot(x,count,data=ccdf(rlnorm(10000,3,2.4)),log='xy') 

Ciò produrrà un grafico in cui l'asse y x & diventano sempre più fitta. Qui sarebbe ideale avere un minor numero di campioni tracciati per grandi valori xey.

Qualcuno ha suggerimenti o suggerimenti per trattare problemi simili?

Grazie, -e

+0

Ciao Rob, Dirk - tengo a precisare che io sono non è alla ricerca di un modo per gestire la sovrapposizione usando un diverso metodo di visualizzazione. In particolare, voglio fare un grafico a punti che io possa incorporare in un foglio LaTeX come grafica vettoriale scalabile. Il modo in cui mi piacerebbe farlo è ridurre il numero di punti di trama necessari per trasmettere i miei dati. – eytan

+0

Quindi il sottocampionamento potrebbe essere la soluzione migliore. Ciò può naturalmente essere fatto con campionamenti "non uniformi", quindi potresti voler tenere più punti (o anche tutti) dalle code, ma puoi permetterti di ridurre drasticamente la parte principale. Ma questo sembra problematico, quindi potresti doverlo cucinare da solo. –

risposta

4

Ecco una possibile soluzione per il plottaggio del diagramma rispetto all'asse x, se è log trasformato. E 'il login trasforma l'asse x, arrotonda tale quantitativo, e raccoglie il valore mediano x in che bin:

downsampled_qplot <- function(x,y,data,rounding=0, ...) { 
    # assumes we are doing log=xy or log=x 
    group = factor(round(log(data$x),rounding)) 
    d <- do.call(rbind, by(data, group, 
    function(X) X[order(X$x)[floor(length(X)/2)],])) 
    qplot(x,count,data=d, ...) 
} 

Utilizzando la definizione di ccdf() dall'alto, possiamo quindi confrontare la trama originale del CCDF della distribuzione con la versione downsampled:

myccdf=ccdf(rlnorm(10000,3,2.4)) 

qplot(x,count,data=myccdf,log='xy',main='original') 

downsampled_qplot(x,count,data=myccdf,log='xy',rounding=1,main='rounding = 1') 

downsampled_qplot(x,count,data=myccdf,log='xy',rounding=0,main='rounding = 0') 

in formato PDF, la trama originale riprende 640K, e le versioni downsampling occupano 20K e 8K, rispettivamente.

+0

anziché arrotondare, si potrebbe anche fare più in generale qualcosa di simile: group = cut (log (dati $ x), b = punti max) – eytan

8

Io tendo ad usare i file png, piuttosto che di grafica vettoriale based come pdf o eps per questa situazione. I file sono molto più piccoli, anche se perdi risoluzione.

Se si tratta di un grafico a dispersione più convenzionale, utilizzare anche i colori semitrasparenti, oltre a risolvere il problema di sovraesposizione. Ad esempio,

x <- rnorm(10000); y <- rnorm(10000) 
qplot(x, y, colour=I(alpha("blue",1/25))) 
5

suggerimenti di là di Rob, una funzione plot mi piace come fa il 'assottigliamento' per voi è hexbin; un esempio è at the R Graph Gallery.

+3

Oppure, con ggplot2, 'geom =" hex "' – hadley

2

avrei subordinare file immagine (dispositivi png o jpeg) come Rob già accennato, o farei un 2D histogram. Un'alternativa alla istogramma 2D è una smoothed scatterplot, fa un grafico simile ma ha un taglio più liscia da regioni di spazio dense a sparse.

Se non hai mai visto addictedtor prima, vale la pena dare un'occhiata. Ha una grafica molto bella generata in R con immagini e codice di esempio.

Ecco il codice di esempio dal sito addictedtor:

2-D istogramma:

require(gplots) 

# example data, bivariate normal, no correlation 
x <- rnorm(2000, sd=4) 
y <- rnorm(2000, sd=1) 

# separate scales for each axis, this looks circular 
hist2d(x,y, nbins=50, col = c("white",heat.colors(16))) 
rug(x,side=1) 
rug(y,side=2) 
box() 

smoothscatter:

library("geneplotter") ## from BioConductor 
require("RColorBrewer") ## from CRAN 

x1 <- matrix(rnorm(1e4), ncol=2) 
x2 <- matrix(rnorm(1e4, mean=3, sd=1.5), ncol=2) 
x <- rbind(x1,x2) 

layout(matrix(1:4, ncol=2, byrow=TRUE)) 
op <- par(mar=rep(2,4)) 
smoothScatter(x, nrpoints=0) 
smoothScatter(x) 
smoothScatter(x, nrpoints=Inf, 
       colramp=colorRampPalette(brewer.pal(9,"YlOrRd")), 
       bandwidth=40) 
colors <- densCols(x) 
plot(x, col=colors, pch=20) 

par(op)