如何根据正/负值对RGL surface3d进行着色?

时间:2016-02-11 17:14:25

标签: r rgl

我有这个代码:(我在stackoverflow上找到了某个地方,只是用它来说明我的想法。)

x<-runif(20) 
y<-runif(20) 
z<-runif(20, -5,5) 

library(rgl) 
plot3d(x,y,z)

fit <- lm(z ~ poly(x,2) +poly(y,2) + x:y )

xnew <- seq(min(x), max(x), len=20) 
ynew <- seq(min(y), max(y), len=20) 
df <- expand.grid(x = xnew, 
                  y = ynew) 

df$z <- predict(fit, newdata=df)

surface3d(xnew, ynew, df$z, col="red")

enter image description here

我的问题是,如何使颜色为零以上的绿色渐变,红色低于零?我清楚了吗?

我发现了这篇文章:Formatting of persp3d plot

这有助于实现渐变,但我无法弄清楚如何使其依赖于z的正/负值,以及如何将其分别限制为绿色和红色。

感谢您的帮助!

编辑:

我尝试在下面做一些事情,添加:

colors<-rep("red", length(df$z))
colors[(df$z > 0)] <- colorRampPalette(c("yellow","green"))(sum(df$z > 0))
colors[(df$z < 0)] <- colorRampPalette(c("red","yellow"))(sum(df$z < 0))

surface3d(xnew, ynew, df$z, col=colors)

产生了这个:

enter image description here

看起来渐变沿着错误的轴。它应该是z = 0附近的黄色,更多的红色aas z变得更负,而更多的绿色,因为z变得更积极。但它并没有这样做,沿着y轴应用渐变(看似)。

思想?

3 个答案:

答案 0 :(得分:1)

您可以使用针对0测试的z值来返回1和0的向量(然后使用1+ - 操作强制转换为2和1):

surface3d(xnew, ynew, df$z, col=c("red","blue")[1+(df$z > 0)] )
rgl.snapshot("zerocol.png",top=FALSE)

您确实在颜色阈值处看到了相当多的锯齿状,因为您的网格相当粗糙。我看到我使用的颜色与请求的颜色略有不同,但原则是先将颜色名称设置为FALSE-z,然后是TRUE-z秒(1 + TRUE == 2)。很酷的马鞍适合我的随机抽奖。

enter image description here

答案 1 :(得分:0)

这是一种类似的方法,它将突出显示绿色&gt; 0和红色&lt; 0:

colors<-rep("red", length(df$z))
colors[(df$z>0.0)]<-"green"
surface3d(xnew, ynew, df$z, col=colors)

使用基色定义数组,更改元素的颜色&gt; 0然后绘制。

编辑:要添加渐变,请检查rgl.surface命令的代码示例。这可能更接近您的期望:

zlenpos<- max(df$z)+1
zlenneg<- 0-min(df$z)
colorscale<-rainbow(zlenpos+zlenneg, start = 0, end = 2/6)
colors<-colorscale[df$z - min(df$z) + 1]
surface3d(xnew, ynew, df$z, col=colors)

执行从红色到黄色到绿色的渐变,但黄色接近z的零。我会把这个留给其他人来改进细节。

答案 2 :(得分:0)

如果将曲面指定为x和y的函数而不是矩阵,则可以使用persp3d.function方法:它将根据z值自动计算出适当的颜色。请参阅?persp3d.function中的第一个示例。

如果您的z是矩阵,则必须复制persp3d.function的内容。您可以使用rgl:::persp3d.function来查看来源。

一般来说,对于像这样的高级别用户,你会想要使用persp3d; surface3d执行表面的低级绘图。