我有这个代码:(我在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")
我的问题是,如何使颜色为零以上的绿色渐变,红色低于零?我清楚了吗?
我发现了这篇文章: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)
产生了这个:
看起来渐变沿着错误的轴。它应该是z = 0附近的黄色,更多的红色aas z变得更负,而更多的绿色,因为z变得更积极。但它并没有这样做,沿着y轴应用渐变(看似)。
思想?
答案 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)。很酷的马鞍适合我的随机抽奖。
答案 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
执行表面的低级绘图。