我有两个栅格图层,一个是灰度图像,另一个是分析结果。我想在ggplot中使用一个栅格作为灰度背景,并使用颜色渐变叠加第二个栅格。这是一个如何(但更好)的例子:
我无法为栅格分配单独的颜色。你知道实现这个目标的方法吗?我用谷歌搜索了很长时间,我觉得这是不可能的。但我不能(并且不想)相信它。
如果您需要进一步的信息,请告诉我。
示例
创建测试数据
xy.1 <- expand.grid(1:10, 1:10)
df.1 <- data.frame(Longitude=xy.1[,1], Latitude=xy.1[,2], Value=xy.1[,1]+xy.1[,2])
xy.2 <- expand.grid(3:5, 3:5)
df.2 <- data.frame(Longitude=xy.2[,1], Latitude=xy.2[,2], Value=rnorm(9))
积
p1 <- ggplot() +
geom_raster(data=df.1, aes(x=Longitude, y=Latitude, fill=Value)) +
scale_fill_gradientn(colours = grey(seq(0,1,l=20))) +
coord_equal() +
theme(legend.position="none")
p1 + geom_raster(data=df.2, aes(x=Longitude, y=Latitude, fill=Value)) +
scale_fill_gradient(low="red", high="white")
结果:
答案 0 :(得分:2)
我编写了一个函数,允许使用ggplot2添加背景并叠加前景栅格。
编辑:我在最后添加了一个更好的解决方案
这是它的工作原理:
我合并了两个栅格并移动了值,使得值不重叠。然后,我使用包含前景色标(例如红色 - >绿色)的比例尺绘制栅格图层,其中背景色标是硬编码的(黑色 - >白色)。颜色数量没有限制。
不显示栅格图层的图例。为了得到一个不包含整个比例尺的图例(黑色 - &gt;白色 - &gt;红色 - &gt;绿色),我在后台插入两个虚拟点。一个具有最小值的前景数据,一个具有最大值。这仅为前景数据提供了图例。
如果有人知道更好的缩放方式和创建色阶,我很乐意将其添加到函数中。
我添加了使用分位数缩放前景数据的可能性;参数fg.quant
采用两个整数的向量,用于“剪切”数据。 bw.scale
允许使背景光栅更暗/更亮:bw.scale=c(0, 0.5)
表示背景图像的颜色范围从黑色到灰色(0.5),例如。
我知道这不是一个完美的功能。但它对我来说非常有用,我会改进它,并在我有空闲时间后尝试消除丑陋的部分。
测试数据
# 'background'
r.1 <- raster(x=matrix(rowSums(expand.grid(1:10, 1:10)), nrow=10),
xmn=0, xmx=10, ymn=0, ymx=10)
# 'foreground'
r.2 <- raster(x=matrix(rnorm(16), nrow=4),
xmn=3, xmx=7, ymn=3, ymx=7)
剧情功能
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# BGPlot() -- plot data with background raster using ggplot2
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BGPlot <- function(fg,
bg,
cols=c('red', 'green'),
fg.quant=c(0, 1),
bw.scale=c(0, 1),
plot.title='',
leg.name='Value') {
# plot data with background raster using ggplot2
#
# Args
# fg: foreground raster layer
# bg: background raster layer
# cols: colors to use for fg
# fg.quant: scaling fg by quantiles
# bw.scale: makes bg darker / brighter:
# E.g. c(0, 0.9) -> darker / c(0.2, 1) -> brighter
# plot.title: title
# leg.name: name to be displyed at legend
#
# Returns
# ggplot object
# load libraries
library(ggplot2)
# get min / max of foreground raster
fg.q <- quantile(fg, fg.quant)
fg.min <- fg.q[1]
fg.max <- fg.q[2]
# rescale fg
fg.sc <- (fg-fg.q[1]) / (fg.q[2]-fg.q[1])
fg.sc[fg.sc<0] <- 0
fg.sc[fg.sc>1] <- 1
fg.sc <- fg.sc + 0.1
# get scale (fg values 0.1, 10, 1000 range?)
ifelse((fg.max-fg.min)/10>=1, n.dgts <- 0, n.dgts <- 1)
# create fg legend breaks / labels
fg.breaks <- round(seq(fg.min, fg.max, l=5), n.dgts)
fg.breaks[1] <- ceiling(fg.min*(10^n.dgts))/(10^n.dgts)
fg.breaks[5] <- floor(fg.max*(10^n.dgts))/(10^n.dgts)
fg.labs <- paste0(c(paste0(round(fg.min, n.dgts+1), '-'),'','','',''),
fg.breaks,
c('','','','',paste0('-', round(fg.max, n.dgts+1)))
)
# rescale bg
bg.sc <- (bg-minValue(bg)) /
(maxValue(bg)-minValue(bg)) *
(bw.scale[2]-bw.scale[1]) + bw.scale[1] -1.1
# merge rasters, fg over bg
r <- merge(fg.sc, bg.sc)
# convert raster to data.frame
r.df <- as.data.frame(rasterToPoints(r))
names(r.df) <- c('Longitude', 'Latitude', 'Value')
# get center of r
mid.Lon <- mean(r.df$Longitude)
mid.Lat <- mean(r.df$Latitude)
# set scale positions
vals <-c(-1.1,-0.1, seq(0.1,1.1,l=length(cols)))
# set dummy-point values
dp <-seq(fg.min,fg.max,l=length(cols))
# plotting;
p <-
ggplot() +
# dummy points: points not visible, needed to display custom scale-bar
geom_point(data=data.frame(x = rep(mid.Lon, length(cols)),
y = rep(mid.Lat, length(cols)),
c = dp),
aes(x, y, color=c)) +
scale_color_gradientn(colours = cols,
breaks=fg.breaks,
labels=fg.labs,
name=leg.name) +
# raster; no scale-bar plotted
geom_raster(data=r.df, aes(x=Longitude, y=Latitude, fill=Value)) +
scale_fill_gradientn(colours = c('black', 'white', cols),
values = vals,
rescaler = function(x,...) x,
oob = identity,
guide = "none") +
ggtitle(label=plot.title) +
theme_light() +
labs(list(x='Lon', y='Lat')) +
theme(axis.text.y=element_text(angle=90, hjust=0.5)) +
coord_equal()
return(p)
}
函数调用
BGPlot(fg=r.2, bg=r.1, cols=c('red', 'green'), fg.quant=c(0.01, 0.99), bw.scale=c(0, 0.8), plot.title='Chlorophyll Concentration', leg.name='CHL')
“真实世界”的例子:
编辑:使用R套餐'RStoolbox'
的更好解决方案使用包RStoolbox
这是一个非常简单和完美的工作解决方案。函数ggR
生成灰度背景图像,函数ggRGB
为RGB背景。
library(ggplot2)
library(RStoolbox)
ggR(BACKGROUND_IMAGE, geom_raster=FALSE) +
geom_raster(...) # here comes standard raster plot