【问题标题】:ggplot2: raster plotting does not work as expected when setting alpha valuesggplot2:设置 alpha 值时,光栅绘图无法按预期工作
【发布时间】:2012-06-26 03:18:24
【问题描述】:

在这里第一次发帖,我希望我遵守网站礼仪。我在网站上找不到并回答,我之前将此发布到 ggplot2 特定组,但目前还没有解决方案。

基本上,我正在尝试使用 ggplot2 覆盖两个栅格,并要求顶部的栅格是半透明的。我有一个从高程数据栅格计算的 hillShade 栅格,我希望将高程栅格叠加到山体阴影栅格上,这样生成的图就不会看起来“平坦”。您可以在下面可重现的 R 代码中看到我的意思。

使用基本图形我可以达到预期的效果,我在下面的代码中包含了一个示例以明确我的意思,但我需要在 ggplot2 中执行此操作。

我无法让它在 ggplot2 中工作。结合栅格使颜色变得有趣(我可以自己绘制每个都可以)。任何人都可以帮助或指出我正确的方向。下面包含自包含、可重现的代码示例。 (对不起,篇幅较长,但我认为最好说清楚)。

#   Load relevant libraries
library(ggplot2)
library(raster)


#   Download sample raster data of Ghana from my Dropbox
oldwd <- getwd()
tmp <- tempdir()
setwd(tmp)
url1 <- "http://dl.dropbox.com/s/xp4xsrjn3vb5mn5/GHA_HS.asc"
url2 <- "http://dl.dropbox.com/s/gh7gzou9711n5q7/GHA_DEM.asc"
f1 <- file.path(tmp,"GHA_HS.asc")
f2 <- file.path(tmp,"GHA_DEM.asc")
download.file(url1,f1)  #File is ~ 5,655Kb
download.file(url2,f2)  #File is ~ 2,645Kb


#   Create rasters from downloaded files
hs <-  raster(f1)
dem <- raster(f2)


#   Plot with base graphics to show desired output
plot(hs,col=grey(1:100/100),legend=F)
plot(dem,col=rainbow(100),alpha=0.4,add=T,legend=F)


#   Convert rasters TO dataframes for plotting with ggplot
hdf <- rasterToPoints(hs); hdf <- data.frame(hdf)
colnames(hdf) <- c("X","Y","Hill")
ddf <- rasterToPoints(dem); ddf <- data.frame(ddf)
colnames(ddf) <- c("X","Y","DEM")


#   Create vectors for colour breaks
b.hs <- seq(min(hdf$Hill),max(hdf$Hill),length.out=100)
b.dem <- seq(min(ddf$DEM),max(ddf$DEM),length.out=100)


#   Plot DEM layer with ggplot()
p1 <- ggplot()+
    layer(geom="raster",data=ddf,mapping=aes(X,Y,fill=DEM))+
    scale_fill_gradientn(name="Altitude",colours = rainbow(100),breaks=b.dem)+
    scale_x_continuous(name=expression(paste("Longitude (",degree,")")),limits=c(-4,2),expand=c(0,0))+
    scale_y_continuous(name=expression(paste("Latitude (",degree,")")),limits=c(4,12),expand=c(0,0))+
    coord_equal()
print(p1)


#   Plot hillShade layer with ggplot()
p2 <- ggplot()+
    layer(geom="raster",data=hdf,mapping=aes(X,Y,fill=Hill))+
    scale_fill_gradientn(colours=grey(1:100/100),breaks=b.hs,guide="none")+
    scale_x_continuous(name=expression(paste("Longitude (",degree,")")),limits=c(-4,2),expand=c(0,0))+
    scale_y_continuous(name=expression(paste("Latitude (",degree,")")),limits=c(4,12),expand=c(0,0))+
    coord_equal()
print(p2)


#   Try to plot both together with transparency on the DEM layer
p3 <- ggplot(hdf)+
    geom_raster(aes(X,Y,fill=Hill))+
    scale_fill_gradientn(colours=grey(1:100/100),breaks=b.hs,guide="none")+
    scale_x_continuous(name=expression(paste("Longitude (",degree,")")),limits=c(-4,2),expand=c(0,0))+
    scale_y_continuous(name=expression(paste("Latitude (",degree,")")),limits=c(4,12),expand=c(0,0))+
    geom_raster(data=ddf,aes(X,Y,fill=DEM),alpha=I(0.4))+
    scale_fill_gradientn(name="Altitude",colours = rainbow(100),breaks=b.dem)+
    coord_equal()
 print(p3)


#   Cleanup downloaded files and return to previous wd
unlink(tmp,recursive=T)
setwd(oldwd)

我的问题如下:

Q1:如何使 p3 的图层看起来像上面示例中使用基础图形绘制时的样子?

Q2:如何更明智地指定色标,以免 RHS 上出现荒谬的传说?

【问题讨论】:

  • 我确信会有一些方法可以使用annotation_raster - 但到目前为止我的尝试都没有结果。您的组合情节失败的原因(如我所见)是对scale_fill_gradientn 的两次调用
  • 这就是它的症结所在。似乎ggplot 只能有一个fill 美学和一个colour 美学。您可以通过将 DEM 层设置为 geom_pointcolour=DEM 然后使用 scale_colour_gradientn 而不是 scale_fill_gradientn 来获得类似的效果,但它看起来不如基本图形方式。
  • 感谢您查看我的问题,你们俩! @mplourde - 我确实认为 ggplot2 每层可以有一个填充美学,但我认为在有 alpha 透明度的地方,它会在图层重叠的地方使用加色混合来组合颜色。不知何故,这种混合在ggplot2中与基本图形不同。我一直在考虑它,我认为我需要做的是从hillShade栅格中的相关灰度值手动计算颜色(我认为这是hcl颜色中的色度模型)和来自 DEM 栅格的色调(我认为这将是色调)。

标签: r graphics plot ggplot2 raster


【解决方案1】:

下个版本会支持光栅中的alpha,所以你可以通过:

ggplot(NULL, aes(X, Y)) + 
  geom_raster(data = ddf, aes(fill = DEM)) + 
  geom_raster(data = hdf, aes(alpha = Hill)) +
  scale_fill_gradientn(name="Altitude",colours = rainbow(20))+
  guides(fill = guide_colorbar()) +
  scale_alpha(range = c(0, 0.5), guide = "none") +
  scale_x_continuous(name=expression(paste("Longitude (",degree,")")), limits=c(-4,2),expand=c(0,0)) +
  scale_y_continuous(name=expression(paste("Latitude (",degree,")")), limits=c(4,12),expand=c(0,0)) +
  coord_equal()

不管怎样,情节很漂亮。

如果您想立即使用它,请尝试从 github 安装:

library(devtools)
install_github("ggplot2", "kohske", "fix/geom-raster-alpha")

请注意,geom_tilegeom_raster 在某些设备中看起来不同。 也许光栅更适合您的目的。

【讨论】:

  • 谢谢!有了这个修复,我现在可以完全按照我的需要进行绘图。太感谢了。干杯,西蒙。
  • 任何人知道如何调整图例中的颜色以匹配地图中的颜色,因为它已经被灰色掩盖了?
  • 在使用 geom_raster() 而不是 geom_tile() 时,文件输出 (PDF) 出现“模糊”光栅问题。后者解决了这个问题。谢谢你的评论。
【解决方案2】:

Q1:您不能在不同的图层上使用不同的填充比例。一种解决方法是对 DEM 使用填充美学,对山体阴影使用 alpha 美学。不幸的是,geom_raster 似乎并没有像我预期的那样使用 alpha 美学。使用geom_tile也可以达到同样的效果,只是需要更长的时间:

ggplot(hdf) +
  geom_raster(data=ddf,aes(X,Y,fill=DEM)) +
  scale_fill_gradientn(name="Altitude",colours = rainbow(100),breaks=b.dem) +
  geom_tile(aes(X,Y,alpha=Hill), fill = "grey20") +
  scale_alpha(range = c(0, 0.5)) +
  scale_x_continuous(name=expression(paste("Longitude (",degree,")")),
    limits=c(-4,2),expand=c(0,0)) +
  scale_y_continuous(name=expression(paste("Latitude (",degree,")")),
    limits=c(4,12),expand=c(0,0)) +
  coord_equal() 

Q2:查看?guide_colorbar。它不适用于 100 种颜色中断,但减少了它就很好了。

ggplot(hdf)+
  geom_raster(data=ddf,aes(X,Y,fill=DEM))+
  scale_fill_gradientn(name="Altitude",colours = rainbow(20))+
  guides(fill = guide_colorbar()) +
  geom_tile(aes(X,Y,alpha=Hill), fill = "grey20") +
  scale_alpha(range = c(0, 0.5)) +
  scale_x_continuous(name=expression(paste("Longitude (",degree,")")),
    limits=c(-4,2),expand=c(0,0)) +
  scale_y_continuous(name=expression(paste("Latitude (",degree,")")),
    limits=c(4,12),expand=c(0,0)) +
  coord_equal() 

【讨论】:

  • 非常感谢您花时间和精力修复我的编码工作。这对我的目的很有用。非常感谢! :-)
猜你喜欢
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2019-12-07
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 2020-12-04
相关资源
最近更新 更多