【问题标题】:Y axis scaling issue with small numbers小数字的 Y 轴缩放问题
【发布时间】:2012-06-09 16:15:34
【问题描述】:

对于小于 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 年 5 月的邮件列表上看到了一个类似的帖子,Hadley 回答说它与 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 

有人知道吗?

提前谢谢你! 蒂博·鲁埃勒

【问题讨论】:

  • +1 快速测试确认了我的系统上的这种行为(ggplot2 0.9.1)。也许有一个回归,或者?
  • @BenBolker 我在聊天中问过布莱恩这个问题,因为与this 上一个问题有联系。
  • @joran 是的,这两个帖子似乎可以合并。很抱歉在我的研究中没有找到它。
  • 如果我没有特别记得看过并评论过上一篇,我可能不会找到它。
  • 但是,手动缩放选项不能(或至少不能)应用于我的案例,因为我有数百个这样的文件要绘制和分析。

标签: r ggplot2 autoscaling


【解决方案1】:

正如 Brian Diggs 在回复 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 
}

您提供的代码运行良好:

【讨论】:

  • 我想你也可以调整all.equal 中的tolerance 参数。
  • @joran -- 知道什么是更好的价值吗?我不知道哈德利试图用这段代码来保护什么病态,所以不知道安全程度有多低......(所以我当然一起去移除了保护;)
  • 好吧,zero_range 通常会传递一个带有最小值/最大值的向量,因此您希望 some 检查它们何时相同。也许只是检查x[1] == x[2]?我觉得这里有浮点边缘情况我不明白。
  • @joran -- 是的,我也不理解那些极端情况。大概是有理由不使用==,但同样清楚的是,默认容差的all.equal()保守了。
  • 我已经更新了一个错误报告:github.com/hadley/ggplot2/issues/550
猜你喜欢
  • 2021-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多