在R中生成光栅图。

5

我正在尝试生成一张栅格图(类似于Hovmoller图),希望有人能帮助我。我已经查看了rasterVis和其他相关帮助文档,但是似乎无法将它们的示例适配到我的数据上。我已经创建了这张图,但是单元格的填充值与原始数据不对应。我复制了一个dput()文件,其中包含我的数据框架的示例(希望这是正确的操作方式)。我想要实现的是,一年中的日数(DOY)沿x轴,每个DOY上方有48个矩形(DF中的小时列),这些矩形代表每个DOY的半小时间隔,并根据它们相应的a值(DF中的qc列),该值为0、1或2,进行颜色着色。

到目前为止,我编写了以下代码,但似乎存在问题,即将z值(qc列)分配给颜色时,这些值似乎没有适当地对齐...

mcol <- c("green","blue","red")
x=unique(DF[,"DOY"])
y=unique(DF[,"hour"])
z=matrix(DF[,"qc"],nrow=length(unique(DF[,"DOY"])),
                     ncol=length(unique(DF[,"hour"])))
image(x,y,z, col=mcol,
  xlab="Day of Year 2012", 
  ylab="Hour of day",
  main="Hovmoller plot of 2012 qc flags",
useRaster=TRUE)

似乎发生的情况是填充值矩阵(z)首先沿着x轴底部(从左到右)应用,然后循环到顶部,而我需要它从左下角开始向上,然后循环从左到右(希望这有点意义!)这里的示例数据仅涵盖三天,但完整数据集将为整个年份(2012年中的366天)。感谢您的任何帮助,Jon。
structure(list(DOY = c(4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L), hour = c(0.5, 1, 1.5, 2, 2.5, 3, 3.5, 
4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 
11.5, 12, 12.5, 13, 13.5, 14, 14.5, 15, 15.5, 16, 16.5, 17, 17.5, 
18, 18.5, 19, 19.5, 20, 20.5, 21, 21.5, 22, 22.5, 23, 23.5, 24, 
0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 
8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 13.5, 14, 14.5, 
15, 15.5, 16, 16.5, 17, 17.5, 18, 18.5, 19, 19.5, 20, 20.5, 21, 
21.5, 22, 22.5, 23, 23.5, 24, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 
4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 
12, 12.5, 13, 13.5, 14, 14.5, 15, 15.5, 16, 16.5, 17, 17.5, 18, 
18.5, 19, 19.5, 20, 20.5, 21, 21.5, 22, 22.5, 23, 23.5, 24), 
    qc = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 1L, 2L, 1L, 1L, 2L, 2L, 0L, 0L, 1L, 0L, 2L, 2L, 2L, 2L, 
    2L, 2L, 0L, 2L, 2L, 0L, 0L, 1L, 2L, 0L, 2L, 0L, 1L, 2L, 1L, 
    2L, 2L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 2L, 2L, 2L, 2L, 0L, 0L, 
    2L, 0L, 0L, 0L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L)), .Names = c("DOY", 
"hour", "qc"), class = "data.frame", row.names = c(NA, -144L))

1
类似于 library(raster);plot(raster(t(z))) 这样的东西? - Roman Luštrik
3个回答

4
接近了!尝试像这样做(x和y由上面的代码生成):
library( sp )
r <- raster(nrows=length(y), ncols=length(x), xmn=min(x), xmx=max(x), ymn=min(y), ymx=max(y))
values(r) <- t(DF$qc)
spplot( r , cuts = 2 )

spplot是来自sp包的一个函数,它使用格子图形并且可以根据您的需求进行极其定制。

enter image description here

如果您想要区分不同的单元格,那么使用geom_tile可能是更好的选择(直到栅格单元格数量变得非常大)。

p <-    ggplot( DF , aes(factor(DOY), hour ) ) + 
    geom_tile( aes(fill = factor(qc) ) , color = "#D9D9D9" ) + 
    scale_fill_brewer(name="QC", type = "div" , palette = "RdBu" )+
    scale_x_discrete( name = "Day" , expand = c(0,0) ) +
    scale_y_continuous( name = "Hour" , limits = c(0.5,24) , expand = c(0,0) , breaks = seq(0,24,2) )+
    coord_equal()
print(p)

enter image description here


感谢回复,但是仍然存在QC值与单元格对齐不良的问题。作为测试,如果您更改所有与DOY4相对应的QC值为1,则应在图形左侧从ymin到ymax出现垂直白线,但实际上并未发生。某种情况下,Z值矩阵未按正确方向运行。 - JonP
谢谢Simon,是的,我确实想要区分单个单元格,你的解决方案非常理想,非常感谢。 - JonP
@JonP 好的!现在你应该在我的回答或者你的回答旁边打勾,表示问题已经得到解答了。 - Simon O'Hanlon

3

好的,现在我已经解决了这个问题,而且还相当简单...

library(ggplot2)
ggplot(DF,aes(DOY,hour,fill=qc))+geom_raster()

抱歉,这比我想象的要简单得多。我更喜欢图例颜色是离散的而不是连续的,但这只是一个小细节。感谢您的建议。 Jon

希望在这个主题中能够既有交流又有信息。希望能在R社区看到更多你的身影。 - Carl Witthoft

0

rasterVis 包中的 hovmoller 函数是为 4D 数据(包括坐标、数值变量和时间索引)而设计的。不过,如果我没记错的话,您需要使用级别图绘制单变量时间序列。

这里我使用 lattice::levelplot 进行示例展示。

首先,我们使用时间索引定义数据:

tt <- seq(as.POSIXct('2013-01-01'), by='hour', length=8760)
vals <- 1:24 - 12.5
myDF <- data.frame(vals, tt)

接下来,我们定义两个辅助函数来从时间索引中提取小时和日期的年份:
hour <- function(x)as.numeric(format(x, '%H'))
DoY <- function(x)as.numeric(format(x, '%j'))

接下来,我们加载包并使用RColorBrewer包中的连续调色板定义主题:

library(lattice)
library(latticeExtra)
myTheme <- custom.theme(region=brewer.pal(n=10, 'RdBu'))

最后,我们准备好显示数据了:
levelplot(vals ~ DoY(tt)*hour(tt),
          data=myDF,
          xlab='Day', ylab='Hour',
          par.settings=myTheme)

levelplot result

对于更完整的解决方案,您可能会对strip函数以及metvurst感兴趣。


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