首页 > 解决方案 > 为ggplot定义新的比例轴变换

问题描述

我正在尝试使用squared为 y 轴创建变换,scales::trans_new但遇到错误。

MWE

data = data.frame(x = 1:10, y = runif(10), z=rnorm(10, 10))

library(ggplot2)
ggplot(data, aes(x, y, size=z)) +
geom_point() +
scale_y_continuous(trans=scales::trans_new("sq", function(x) x^2, function(x) x^(1/2)))

给出错误

if (zero_range(as.numeric(limits))) { 中的错误:
需要 TRUE/FALSE 的缺失值

我尝试添加limitsdomain但得到了同样的错误。

scale_y_continuous(trans=scales::trans_new("sq", function(x) x^2, function(x) x^(1/2)), limits=c(0,1))
scale_y_continuous(trans=scales::trans_new("sq", function(x) x^2, function(x) x^(1/2), domain=c(0,1)), limits=c(0,1))

这似乎inverse是导致错误的论点 - 但 的所有值y都是正数,所以我不明白。请问我该怎么做?

标签: rggplot2

解决方案


似乎 ggplot 正在使用反函数来设置 y 轴范围和轴标签。如果 y 接近零,则 gglot 正在填充下限并计算负值。这是美化限制的“负面”(双关语)副作用。

这是一种解决方法,修改反函数以防止它接受小于零的值,它将避免负数误差的平方根。
轴的下限将始终大于或等于零。

library(ggplot2)

#square function
sq<-function(x){
  x^2
}
#inverse square function (square root)
isq<-function(x){
  print(paste("isq",x))  #debug statement
  x<-ifelse(x<0, 0, x)
  sqrt(x)
}

data =  data.frame(x = 1:10, y = runif(10), z=rnorm(10, 10))

print(data$y)
ggplot(data, aes(x, y, size=z)) +
  geom_point() +
  scale_y_continuous(trans=scales::trans_new("sq", sq, isq))

注意:转移到生产代码时删除打印功能。

有关 Github 上的错误报告,请参阅下面评论中的链接。


推荐阅读