如何根据 positive/negative 值给 RGL surface3d 上色?
How to color RGL surface3d based on positive/negative values?
我有这段代码:(我在Whosebug的某个地方找到的,只是用它来说明我的想法。)
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")
我的问题是,如何使颜色在零以上为绿色,在零以下为红色?我说清楚了吗?
我找到了这个 post:Formatting of persp3d plot
这有助于渐变,但我不知道如何使它依赖于 z 的 positive/negative 值,以及如何将其分别限制为绿色和红色。
感谢您的帮助!
编辑:
我尝试在下面做一些事情,添加这个:
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 附近呈黄色,随着 z 变得更负,变得更红,随着 z 变得更正,变得更绿。但它并没有这样做,而是沿 y 轴(看似)应用渐变。
想法?
您可以使用针对 0 测试的 z 值到 return 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) 的顺序放置。很酷的马鞍适合我的随机抽奖。
这是一个类似的方法,它会突出显示绿色>0 和红色<0:
colors<-rep("red", length(df$z))
colors[(df$z>0.0)]<-"green"
surface3d(xnew, ynew, df$z, col=colors)
定义一个基色数组,改变>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 的零。我会把这个留给其他人来完善细节。
如果您的表面被指定为 x 和 y 的函数而不是矩阵,您可以使用 persp3d.function
方法:它会根据 z 值自动计算出合适的颜色。请参阅 ?persp3d.function
中的第一个示例。
如果你的 z 是一个矩阵,你将不得不复制 persp3d.function
所做的。您可以使用 rgl:::persp3d.function
.
查看来源
通常对于像这样的高级事物,您会想要使用 persp3d
; surface3d
进行表面的低级绘图。
我有这段代码:(我在Whosebug的某个地方找到的,只是用它来说明我的想法。)
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")
我的问题是,如何使颜色在零以上为绿色,在零以下为红色?我说清楚了吗?
我找到了这个 post:Formatting of persp3d plot
这有助于渐变,但我不知道如何使它依赖于 z 的 positive/negative 值,以及如何将其分别限制为绿色和红色。
感谢您的帮助!
编辑:
我尝试在下面做一些事情,添加这个:
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 附近呈黄色,随着 z 变得更负,变得更红,随着 z 变得更正,变得更绿。但它并没有这样做,而是沿 y 轴(看似)应用渐变。
想法?
您可以使用针对 0 测试的 z 值到 return 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) 的顺序放置。很酷的马鞍适合我的随机抽奖。
这是一个类似的方法,它会突出显示绿色>0 和红色<0:
colors<-rep("red", length(df$z))
colors[(df$z>0.0)]<-"green"
surface3d(xnew, ynew, df$z, col=colors)
定义一个基色数组,改变>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 的零。我会把这个留给其他人来完善细节。
如果您的表面被指定为 x 和 y 的函数而不是矩阵,您可以使用 persp3d.function
方法:它会根据 z 值自动计算出合适的颜色。请参阅 ?persp3d.function
中的第一个示例。
如果你的 z 是一个矩阵,你将不得不复制 persp3d.function
所做的。您可以使用 rgl:::persp3d.function
.
通常对于像这样的高级事物,您会想要使用 persp3d
; surface3d
进行表面的低级绘图。