使用ggplot的sec.axis与非单调变换

hal*_*ass 5 r ggplot2

我想使用ggplotsec.axis选项生成第二个X轴(称为Z),显示转换Z = X + sqrt(X ^ 2--X)。这种变换通常不是单调的,而是在我的应用程序可能达到的X范围内(X> 1)单调的。

我尝试了以下方法:

x1 = seq(1, 3.5, .1)
y = rnorm( n = length(x1) )

d = data.frame( x1, y )

library(ggplot2)
ggplot( d, aes( x=x1, y=y ) ) + geom_point() +
  scale_x_continuous( sec.axis = sec_axis( ~ . + sqrt(.^2 - .) ) )
Run Code Online (Sandbox Code Playgroud)

导致和错误以及警告:

Error in f(..., self = self) : 
  transformation for secondary axes must be monotonous
In addition: Warning message:
In sqrt(.^2 - .) : NaNs produced
Run Code Online (Sandbox Code Playgroud)

这些都表明它正在尝试计算X <1的值的变换,即使这对于绘图来说不是必需的。

如何绘制有效的单调变换?我需要一个合理的通用解决方案,因为要使用的函数的X范围部分由用户指定(但始终> 1)。

ton*_*nov 6

好吧,你可以欺骗 ggplot 相信它是单调的:

f <- Vectorize(function(x) {
  if (x < 1) return(x/1e10)
  x + sqrt(x^2 - x)
})

ggplot( d, aes( x=x1, y=y ) ) + geom_point() +
scale_x_continuous(sec.axis = sec_axis(~f(.)))
Run Code Online (Sandbox Code Playgroud)

使用expand = c(0, 0)很好,但它会减少绘图区域。