使用 R 和 Lattice 的 XYZ 图中高程数据的颜色渐变

Color gradient for elevation data in a XYZ plot with R and Lattice

我有一堆 XYZ 数据,其中 X 和 Y 是坐标,Z 应该是高程(LiDAR 点)。我正在尝试使用基于 Z 值的梯度绘制此点云。

这是我目前的情况:

# Read the CSV file with the LiDAR point cloud (which was conveniently converted to CSV)
myData <- read.csv("./52I212_plot10.las.csv")
# We don't need all attributes, let's keep only X, Y and Z.
myData <- subset(myData, select=c(X,Y,Z))
# We want a normalized version of Z (between 0 and 1)
myData$normalZ <- (myData$Z-min(myData$Z))/(max(myData$Z)-min(myData$Z))
str(myData)

有了这个,我尝试用

创建情节
library(lattice)
ramp <- colorRampPalette(c("lightblue", "red"))
cloud(myData$Z ~ myData$X + myData$Y, xlab="X", ylab="Y", zlab="Z",pch=20,
  col.point=ramp(10)[myData$normalZ*10]) 

我希望 Z 值具有介于浅蓝色和红色之间的十种可能颜色之一。

当我将绘图命令更改为

cloud(myData$Z ~ myData$X + myData$Y, xlab="X", ylab="Y", zlab="Z",pch=20,
  col.point=gray(myData$normalZ))

我得到的东西更接近我的需要:

我怀疑我在色带上做错了什么,但不知道是什么。

提前致谢

拉斐尔

编辑

这个问题:How to match vector values with colours from a colour ramp in R?对我帮助很大,但我还是不明白我做错了什么。此代码有效:

myData$normalZ <- (myData$Z-min(myData$Z))/(max(myData$Z)-min(myData$Z))
ramp <- colorRamp(c("lightblue", "red"))
cols <- ramp(myData$normalZ)
cloud(myData$Z ~ myData$X + myData$Y, xlab="X", ylab="Y", zlab="Z",pch=20,
      col.point=rgb(cols,maxColorValue = 256))

请指出可以对原始代码进行哪些更改以使其正常工作——我不明白为什么第一个图中的颜色看起来是随机的。

谢谢 拉斐尔

没有数据无法确认,但我认为 0 会让你失望。您的 normalZ 介于 0 和 1 之间,因此 10 * normalZ 介于 0 和 10 之间。您将这些非整数传递给 [ 并且它们会向下舍入。 (我不得不查一下,但是来自 ?"[":"Numeric values [of i] are coerced to integer as by as.integer (and hence truncated towards zero)"。

0(或任何小于 1 的值)作为子集索引会扰乱您的颜色向量的长度,从而扰乱事物的匹配方式:

ramp(10)[c(0, 0.4, 0.8, 1.2, 1.6)]
# [1] "#ACD8E5" "#ACD8E5"

然后回收太短的向量。因此,您的代码可能适用于

col.point = ramp(10)[ceiling(myData$normalZ * 10)]

在将 z 值映射到色带中的索引时存在一个小错误。

library(lattice)

N <- 500
myData <- data.frame(X = runif(N,0,30),
                     Y = runif(N,0,30),
                     Z = runif(N,0,300))

myData$normalZ <- (myData$Z-min(myData$Z))/(max(myData$Z)-min(myData$Z))

ramp <- colorRampPalette(c("lightblue", "red"))

cloud(myData$Z ~ myData$X + myData$Y, xlab="X", ylab="Y", zlab="Z",pch=20,
      col.point=ramp(10)[myData$normalZ*10])

这里 myData$normalZ*10 将 (0,1) 中的 Z 值映射到颜色索引 (0,10) 上。 (浮点值在索引时被截断为整数。)但是 ramp(10) 只有 returns 10(不是 11)个元素,并且 R 向量索引必须从 1 而不是 0 开始,所以对于小的 Z 值 NULL 将被退回。这两种效果都会破坏正确的颜色插值。

云看起来像这样,沿 Z 轴着色不正确:

像这样正确插值

cloud(myData$Z ~ myData$X + myData$Y, xlab="X", ylab="Y", zlab="Z",pch=20,
      col.point=ramp(10)[myData$normalZ*9+1])

returns 符合预期的结果: