使用 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 符合预期的结果:
我有一堆 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 符合预期的结果: