2012-06-05 12 views
5

Ho un problema con il ridimensionamento y per i numeri inferiori a 1e-10: appaiono tutti sulla stessa linea orizzontale.Problema di ridimensionamento dell'asse Y con piccoli numeri

Ecco un esempio riproducibile:

file <- structure(list(I = c(-7.254574e-11, -5.649333e-11, -5.015416e-11, 
-4.228137e-11, -3.287486e-11, -2.714915e-11, -2.203692e-11, -1.784489e-11, 
-1.150574e-11, -1.058553e-11, -6.189018e-12, -3.735149e-12, -2.303724e-12, 
6.610914e-13, 1.274374e-12, -3.610768e-13, 5.465134e-12, 6.691699e-12, 
8.020478e-12, 1.139353e-11, 1.537988e-11, 1.926399e-11, 2.130825e-11, 
2.45791e-11, 3.204071e-11, 3.582262e-11, 4.287535e-11, 4.624839e-11, 
5.16657e-11, 6.035387e-11), V = c(-2, -1.867, -1.733, -1.6, -1.467, 
-1.333, -1.2, -1.067, -0.933, -0.8, -0.667, -0.533, -0.4, -0.267, 
-0.133, 0, 0.133, 0.267, 0.4, 0.533, 0.667, 0.8, 0.933, 1.067, 
1.2, 1.333, 1.467, 1.6, 1.733, 1.867)), .Names = c("I", "V"), class = "data.frame", row.names = c(NA, 
-30L)) 

plot(file$V,file$I) 

gg <- ggplot(file,aes(x = V,y=I)) 
print(gg + geom_point()) 

Come si può vedere, utilizzando la funzione plot di base i punti vengono visualizzati correttamente durante l'utilizzo ggplot2 sono visualizzati su una linea orizzontale.

Ho visto un post simile sulla mailing list nel maggio 2011, a cui Hadley ha risposto che funzionava con la versione di sviluppo di ggplot2. Tuttavia, utilizzando la versione R descritta di seguito ho ancora l'errore.

> sessionInfo() 
R version 2.15.0 (2012-03-30) 
Platform: i686-pc-linux-gnu (32-bit) 

locale: 
[1] LC_CTYPE=fr_FR.UTF-8  LC_NUMERIC=C    LC_TIME=fr_FR.UTF-8  
[4] LC_COLLATE=fr_FR.UTF-8  LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8 
[7] LC_PAPER=C     LC_NAME=C     LC_ADDRESS=C    
[10] LC_TELEPHONE=C    LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C  

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] tikzDevice_0.6.2 filehash_2.2-1 scales_0.2.0  plyr_1.7.1  reshape2_1.2.1 
[6] ggplot2_0.9.0 

loaded via a namespace (and not attached): 
[1] colorspace_1.1-1 dichromat_1.2-4 digest_0.5.2  grid_2.15.0  MASS_7.3-18  
[6] memoise_0.1  munsell_0.3  proto_0.3-9.2  RColorBrewer_1.0-5 stringr_0.6  
[11] tools_2.15.0 

Qualcuno ha un indizio?

Grazie in anticipo! Thibaud Ruelle

+0

+1 un test rapido conferma questo comportamento sul mio sistema (ggplot2 0.9.1). Forse c'è stato un ritorno o? –

+0

@BenBolker Ho chiesto a Brian di questo in chat, data la connessione a [questo] (http://stackoverflow.com/q/10808056/324364) domanda precedente. – joran

+0

@joran Sì, sembra che i due post possano essere uniti. Scusa per non averlo trovato con la mia ricerca. –

risposta

3

Come ha commentato Brian Diggs in risposta a a related post that @joran pointed to above, il problema è causato dalla funzione scales::zero_range(). Utilizza all.equal() per verificare se i valori y più piccoli e più grandi sono compresi tra tolerance = .Machine$double.eps^0.5 = 1.490116e-08; se lo sono, i dati vengono tracciati con la "scala zero" utilizzata nel tuo esempio.

Come correzione temporanea, è possibile utilizzare fixInNamespace() per rimuovere il bit offendente di zero_range().

library(scales) ## (The scales package needs to be on your search path) 
fixInNamespace("zero_range", pos="package:scales") 

Nell'editor lanciato da fixInNamespace(), sostituire questa definizione di zero_range():

function (x) 
{ 
    length(x) == 1 || isTRUE(all.equal(x[1] - x[2], 0)) 
} 

con questo (avendo cura di salvare la versione modificata):

function (x) 
{ 
    length(x) == 1 
} 

Il codice fornito quindi funziona bene:

enter image description here

+0

Si potrebbe anche regolare l'argomento 'tolerance' in' all.equal', suppongo. – joran

+0

@joran - Qualche idea su quale sarebbe il valore migliore? Non so quale patologia Hadley stia cercando di proteggere con questo pezzetto di codice, quindi non so quanto in basso sia sicuro andare ... (Quindi ovviamente sono andato e ho rimosso la protezione tutti insieme;) –

+0

Bene, ' zero_range' è generalmente passato un vettore con il minimo/massimo, quindi vuoi che _some_ controlli lì quando sono gli stessi. Forse basta controllare se 'x [1] == x [2]'? Mi sento come se ci fossero casi limite in virgola mobile qui non capisco. – joran

Problemi correlati