如何使用 ``ggplot2`` 从数字矩阵绘制栅格

How to plot a raster from a numeric matrix with ``ggplot2``

我希望基于数字矩阵创建多面栅格图。构面由矩阵中的行定义。

以下示例数据表示 2 x 1 单元格形状(“形状”)可以水平和垂直放置在 3 x 3 网格上的所有方式。

m1 <- matrix(c(1,0,0,1,0,0,0,0,0,
               0,0,0,1,0,0,1,0,0,
               0,1,0,0,1,0,0,0,0,
               0,0,0,0,1,0,0,1,0,
               0,0,1,0,0,1,0,0,0,
               0,0,0,0,0,1,0,0,1,
               1,1,0,0,0,0,0,0,0,
               0,1,1,0,0,0,0,0,0,
               0,0,0,1,1,0,0,0,0,
               0,0,0,0,1,1,0,0,0,
               0,0,0,0,0,0,1,1,0,
               0,0,0,0,0,0,0,1,1), ncol = 9, byrow = TRUE)

矩阵中的每一行代表 Shape 的一个可能位置。这样,将一行格式化为具有三列的矩阵将说明位置(1 = 占用的单元格和 0 = 未占用的单元格)。

matrix(m1[1,], ncol = 3, byrow = TRUE)
#>      [,1] [,2] [,3]
#> [1,]    1    0    0
#> [2,]    1    0    0
#> [3,]    0    0    0

reprex package (v2.0.1)

于 2022-05-03 创建

如图所示,第一个位置是左上角的垂直放置。

我可以使用 anotated_customgrid::rasterGrob 函数用 ggplot2 绘制它。

library(ggplot2)
library(grid)

m1 <- matrix(c(1,0,0,1,0,0,0,0,0,
               0,0,0,1,0,0,1,0,0,
               0,1,0,0,1,0,0,0,0,
               0,0,0,0,1,0,0,1,0,
               0,0,1,0,0,1,0,0,0,
               0,0,0,0,0,1,0,0,1,
               1,1,0,0,0,0,0,0,0,
               0,1,1,0,0,0,0,0,0,
               0,0,0,1,1,0,0,0,0,
               0,0,0,0,1,1,0,0,0,
               0,0,0,0,0,0,1,1,0,
               0,0,0,0,0,0,0,1,1), ncol = 9, byrow = TRUE)

#create a raster grob object from the first row of the matrix  

g <- grid::rasterGrob(matrix(m1[1,], ncol = 3, byrow = TRUE),
                      interpolate = FALSE)

#adjust the colours
g$raster[g$raster == "#FFFFFF"] <- "#0000FF"
g$raster[g$raster == "#000000"] <- "#FFFFFF"

g$raster
#>      [,1]      [,2]      [,3]     
#> [1,] "#0000FF" "#FFFFFF" "#FFFFFF"
#> [2,] "#0000FF" "#FFFFFF" "#FFFFFF"
#> [3,] "#FFFFFF" "#FFFFFF" "#FFFFFF"

ggplot() +
  annotation_custom(g) +
  coord_equal() +
  theme(
    panel.border = element_rect(colour = "#000000", fill = "transparent")
  )

reprex package (v2.0.1)

于 2022-05-03 创建

一次只对一个位置有效。

但是,我的 objective 是为每一行(位置)绘制一个面板,以便我可以一起查看它们。

我用它来说明一个函数的输出,该函数根据提供的网格大小和形状长度创建初始矩阵。因此解决方案必须足够灵活以适应初始矩阵中的可变大小和复杂性。

我使用 ggplot2 是出于习惯,但我对其他方法持开放态度。

问题:

如何创建多面图,其中每个面板代表矩阵中的一行,并设置为栅格格式?

您需要将矩阵重塑为合适的数据框:

df <- data.frame(fill = factor(c(t(m1))),
                 row = factor(rep(rep(1:3, each = 3), len = length(m1)), 3:1),
                 col = factor(rep(1:3, len = length(m1))),
                 fac = factor(rep(seq(nrow(m1)), each = ncol(m1))))

那么剧情就直白了:

ggplot(df, aes(col, row, fill = fill)) +
  geom_tile() +
  facet_wrap(.~fac) +
  coord_equal() +
  scale_fill_manual(values = c(`1` = "navy", `0` = "white"))