2012-06-05 1 views
5

У меня проблема с y-масштабированием для чисел, меньших 1e-10: все они отображаются на одной горизонтальной линии.Проблема масштабирования оси Y с небольшими номерами

Вот воспроизводимый пример:

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()) 

Как вы можете видеть, используя функцию базового участка точки отображаются корректно при использовании ggplot2 они отображаются на горизонтальной линии.

Я видел подобный пост в списке рассылки в мае 2011 года, на который Хэдли ответил, что он работал с версией разработки ggplot2. Однако, используя описанную ниже версию R, я все равно получаю ошибку.

> 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 

У кого-нибудь есть ключ?

Спасибо заранее! Thibaud Ruelle

+0

+1 быстрый тест подтверждает это поведение в моей системе (ggplot2 0.9.1). Может, была реверсия, или? –

+0

@BenBolker Я спросил Брайана об этом в чате, учитывая подключение к [this] (http://stackoverflow.com/q/10808056/324364) предыдущего вопроса. – joran

+0

@joran Да, кажется, что две должности могут быть объединены. Извините, что не нашел его в своих исследованиях. –

ответ

3

Как писал Брайан Диггс в ответ на a related post that @joran pointed to above, проблема связана с функцией scales::zero_range(). Он использует all.equal() для проверки того, находятся ли наименьшие и наибольшие значения y в пределах tolerance = .Machine$double.eps^0.5 = 1.490116e-08 друг друга; если они есть, данные строятся с использованием «нулевой шкалы», используемой в вашем примере.

В качестве временного исправления вы можете использовать fixInNamespace(), чтобы удалить оскорбительный бит zero_range().

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

В редакторе запущенном fixInNamespace() заменить это определение zero_range():

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

с этим (убедившись, чтобы сохранить отредактированную версию):

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

код, который вы после чего выполняется просто отлично:

enter image description here

+0

Вы также можете настроить аргумент 'tolerance' в' all.equal', я полагаю. – joran

+0

@joran - Любая идея, что было бы лучше? Я не знаю, какую патологию Хэдли пытается защитить от этого кусочка кода, поэтому не знаю, насколько это безопасно ... (Конечно, я пошел и удалил защиту все вместе;) –

+0

Ну, ' zero_range' обычно передается вектором с min/max, поэтому вы хотите, чтобы _some_ проверяли там, когда они одинаковы. Возможно, просто проверьте, есть ли 'x [1] == x [2]'? Я чувствую, что здесь есть случаи с плавающей запятой, которые я не понимаю. – joran