R with color gradient
Below is a 3D curve using the R persp3d function and specifying colors.
library(rgl)
y = seq(-5,25,by=0.1)
x = seq(5,20,by=0.2)
NAs <- rep(NA, length(x)*length(y))
z <- matrix(NAs, length(x), byrow = T)
for(i in seq(1,length(x))) {
for(j in seq(1,length(y))) {
val = x[i] * y[j]
z[i,j] = val
if(z[i,j] < 0.02) {
z[i,j] = NA
}
}
}
col <- rainbow(length(x))[rank(x)]
open3d()
persp3d(x,y,z,color=col,xlim=c(5,20),ylim=c(5,10),axes=T,box=F,xlab="X Axis",ylab="Y Axis",zlab="Z Axis")
And it creates this image:
In the current version, for a value of x 15, the color is blue, regardless of the value of z. But I would like the high z-values ββto be dark blue, while the low z-values ββto be blue, if that makes sense. How can I do something like this so that the color not only distinguishes the x values ββbut also the z values?
source to share
To do this, you have to play with HSV colors rather than RGB. It's easier for me.
See my example code below.
library(rgl)
y = seq(-5,25,by=0.1)
x = seq(5,20,by=0.2)
NAs <- rep(NA, length(x)*length(y))
z <- matrix(NAs, length(x), byrow = T)
for(i in seq(1,length(x))) {
for(j in seq(1,length(y))) {
val = x[i] * y[j]
z[i,j] = val
if(z[i,j] < 0.02) {
z[i,j] = NA
}
}
}
Create a unique color for each x value.
col <- rainbow(length(x))[rank(x)]
Create a grid of colors by repeating col
length(y)
times
col2 <- matrix(rep(col,length(y)), length(x))
for(k in 1:nrow(z)) {
row <- z[k,]
rowCol <- col2[k,]
rowRGB <- col2rgb(rowCol) #convert hex colors to RGB values
rowHSV <- rgb2hsv(rowRGB) #convert RGB values to HSV values
row[is.na(row)] <- 0
v <- scale(row,center=min(row), scale=max(row)-min(row)) # scale z values to 0-1
rowHSV['s',] <- v #update s or v values by our scaled values above
# rowHSV['v',] <- v # try changing either saturation or value i.e. either s or v
newRowCol <- hsv(rowHSV['h',], rowHSV['s',], rowHSV['v', ]) #convert back to hex color codes
col2[k,] <- newRowCol #Replace back in original color grid
}
open3d()
persp3d(x,y,z,color=col2,xlim=c(5,20),ylim=c(5,10),axes=T,box=F,xlab="X Axis",ylab="Y Axis",zlab="Z Axis")
This should lead to the following. You can play around scaling the saturation or color value to get the desired "lightness" or "dark" hues.
source to share
All you had to change was this one line:
library(rgl)
y = seq(-5,25,by=0.1)
x = seq(5,20,by=0.2)
NAs <- rep(NA, length(x)*length(y))
z <- matrix(NAs, length(x), byrow = T)
for(i in seq(1,length(x))) {
for(j in seq(1,length(y))) {
val = x[i] * y[j]
z[i,j] = val
if(z[i,j] < 0.02) {
z[i,j] = NA
}
}
}
col <- rainbow(length(z))[rank(z)] # This line changed
open3d()
persp3d(x,y,z,color=col,xlim=c(5,20),ylim=c(5,10),axes=T,box=F,xlab="X Axis",ylab="Y Axis",zlab="Z Axis")
source to share