I wish to create a facetted raster plot based on a numeric matrix. The facets are defined by rows in the matrix.
The following sample data represents all the ways a 2 x 1 cell shape (the "Shape") may be placed horizontally and vertically on a 3 x 3 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)
Each row in the matrix represents a possible position for the Shape. Such that, formatting a row as a matrix with three columns will illustrate the position (1 = occupied cell and 0 = unoccupied cell).
matrix(m1[1,], ncol = 3, byrow = TRUE)
#> [,1] [,2] [,3]
#> [1,] 1 0 0
#> [2,] 1 0 0
#> [3,] 0 0 0
Created on 2022-05-03 by the reprex package (v2.0.1)
As shown, the first position is a vertical placement in the top left corner.
I can plot this with ggplot2
using anotated_custom
and the grid::rasterGrob
function.
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")
)
Created on 2022-05-03 by the reprex package (v2.0.1)
This works fine for one position at a time.
However, my objective is to plot a panel for each row (position) so I can view them all together.
I am using this to illustrate the output of a function that creates the initial matrix based on Grid size and Shape lengths provided. So the solution must be flexible enough to accomodate variable size and complexity in the initial matrix.
I am using ggplot2
out of habit, but I am open to other approaches.
How do I create a facetted plot, where each panel represents a row from a matrix, and formatted as a raster?
You need to reshape your matrix into an appropriate data frame:
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))))
Then the plot becomes straightforward:
ggplot(df, aes(col, row, fill = fill)) +
geom_tile() +
facet_wrap(.~fac) +
coord_equal() +
scale_fill_manual(values = c(`1` = "navy", `0` = "white"))