如何使用 ``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_custom
和 grid::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"))
我希望基于数字矩阵创建多面栅格图。构面由矩阵中的行定义。
以下示例数据表示 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_custom
和 grid::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"))