使用ggplot2和raster软件包绘制几何参考光栅图像的原始颜色-R

4
我想使用>>地理参考栅格图像<<(tif文件)的原始colortable作为ggplot/ggplot2绘制的地图的彩色刻度。由于找不到更简单的解决方案,我通过访问已加载的栅格图像(object)raster1legend属性中的colortable槽来实现此目的。请注意,应保留HTML标签。
raster1 <- raster(paste(workingDir, "/HUEK200_Durchlaessigkeit001_proj001.tif", sep="", collapse=""))
raster1.pts <- rasterToPoints(raster1)
raster1.df <- data.frame(raster1.pts)
colTab <- attr(raster1, "legend")@colortable

好的,目前为止都很好。现在我只需要将colortable应用为我的现有绘图的彩色比例尺:

(ggplot(data=raster1.df)
+ geom_tile(aes(x, y, fill=raster1.df[[3]]))
+ scale_fill_gradientn(values=1:length(colTab), colours=colTab, guide=FALSE)
+ coord_fixed(ratio=1)
)

很不幸,这并没有按预期工作。生成的图像除了白色和典型的ggplot灰色之外,并没有显示任何颜色,通常在未定义自定义值时会出现。目前,我有点不知道实际上出了什么问题。我假设存储在中的基础波段值是颜色表的索引。这可能是错误的。如果它是错误的,那么波段值如何与相关联呢?即使我的假设是正确的:我给的参数仍然应该产生更多彩色的图形,不是吗?我检查了独特的值是什么:
sort(unique(raster1.df[[3]]))

这会输出:

 [1]  0  1  2  3  4  5  6  7  8  9 10 11 12

显然,并非所有256个成员都使用了,这让我想起颜色并不总是需要反映底层波段数据分布(尤其是包含多个波段时)。
希望我的最后思考没有让您对目标产生困惑。
感谢您的帮助!

这次的解决方案是太明显了还是太隐蔽了? :) - Florian R. Klein
好的,现在我知道问题出在哪里了:scale_fill_gradientn函数的values参数只接受0到1之间的值。我必须手动为colortable中所有唯一颜色进行缩放。完成后我会将其发布为答案。但是还有一个问题尚未解决:栅格数据瓦片后面的栅格数据值并不完全反映所有使用的颜色,因为tif图像使用白色作为无值和黑色来轮廓化区域。必须有一种方法可以获取每个栅格像素/瓦片的原始颜色值。 - Florian R. Klein
如果一个地理参考图像包含图案而不仅仅是简单的颜色填充,那么颜色数量和带数据值之间的差异会更加明显。每个单元可能有很多不同的颜色,这取决于它的图案以及是否有边框等因素。 - Florian R. Klein
1个回答

3

好的,我找到了一个答案,虽然它可能不适用于所有地理参考栅格图像,但或许适用于大部分。

首先,我的假设是数据值并不完全代表颜色选择,这是错误的。空间栅格对象的colortable中有15种独特的颜色。然而,并非所有颜色都被使用(14和15)。现在我知道,我必须将我的值映射到相应的颜色上,这样scale_fill_gradientn就能够理解了。为此,我正在使用之前的初始代码片段,并定义一个新变量valTab,其中存储给定波段的所有唯一数据值:

raster1 <- raster(paste(workingDir, "/HUEK200_Durchlaessigkeit001_proj001.tif", sep="", collapse=""))
raster1.pts <- rasterToPoints(raster1)
raster1.df <- data.frame(raster1.pts)
raster1.img <- melt(raster1)
colTab <- attr(raster1, "legend")@colortable
names(colTab) <- 0:(length(colTab) - 1)
valTab <- sort(unique(raster1.df[[3]]))

请注意,colTab 中的索引名称是如何定义的 - 这很快就会变得重要。有了这个,我可以在绘图时自动关联所有活动颜色及其相应的值:

(ggplot(data=raster1.df)
+ geom_tile(aes(x, y, fill=raster1.df[[3]]))
+ scale_fill_gradientn(colours=colTab[as.character(valTab)])
+ coord_fixed(ratio=1)
)

使用valTab成员作为对应颜色索引的引用有助于始终仅选择所需的颜色。我不知道在某些情况下是否需要定义scale_fill_gradientn()values参数。
我不确定由raster()读取的光栅图像是否总是从0开始定义它们的值。如果不是,则需要调整names(colTab) <- 0:(length(colTab)-1)
希望这能帮助将来的某个人。至少,我终于有了一个解决方案!

您可以使用raster包中的函数colortable来访问颜色表。 - user3710546
@Florian R. Klein:我正在尝试复现这个解决方案,但是我并没有真正做到。你使用raster1.img <- melt(raster1)实现了什么?你是否使用了reshape2包中的melt()函数?而且你真的想要“融化”你的栅格文件吗?我本来会期望使用melt(raster1.df) - Ratnanil
同样的问题,只是数据稍有不同,解决方案在这里:https://dev59.com/R5Dea4cB1Zd3GeqPcHyl#33367160 - Ratnanil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接