I have a boolean matrix:
mm <- structure(c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE,
FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE,
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE,
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE,
TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE,
TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE,
TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE,
TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE,
TRUE, TRUE, TRUE), .Dim = c(10L, 10L), .Dimnames = list(NULL,
c("n1", "n2", "n3", "n4", "n5", "n1.1", "n2.1", "n3.1", "n4.1",
"n5.1")))
For this matrix, I'd like to make a plot similar to this one:
(the picture was taken from a similar question for Matlab: How can I display a 2D binary matrix as a black & white plot?)
Maybe I'm missing something obvious, but I don't see an easy way how to do that in R. So far, my best attempt is based on barplot:
m1 <- matrix(TRUE,ncol=10,nrow=10)
barplot(m1,col=mm)
but it makes all rows have the same colors.
Any ideas are welcome
You can do this using ggplot2's geom_tile
and reshape2's melt
:
library(ggplot2)
library(reshape2)
melted <- melt(mm)
ggplot(melted, aes(x = Var2, y = Var1, fill = value)) + geom_tile() +
scale_fill_manual(values = c("white", "black"))
To make it a bit neater, you could remove the legend and the gray edges with some adjustments to the theme:
ggplot(melted, aes(x = Var2, y = Var1, fill = value)) + geom_tile() +
scale_fill_manual(values = c("white", "black")) +
theme_bw() +
theme(legend.position = "none")
Final output:
Here are a few more approaches to round out the graphics options.
base graphics with rect
:
plot.new()
par(mar=rep(0, 4))
plot.window(xlim=c(0, ncol(mm)), ylim=c(0, nrow(mm)), asp=1)
o <- cbind(c(row(mm)), c(col(mm))) - 1
rect(o[, 1], o[, 2], o[, 1] + 1, o[, 2] + 1, col=t(mm)[, ncol(mm):1])
lattice::levelplot
and latticeExtra
:
library(latticeExtra)
levelplot(t(mm)[, ncol(mm):1], asp=1, scales='sliced',
col.regions=c('white', 'black'), margin=FALSE, colorkey=FALSE) +
layer(panel.grid(h=nrow(mm)-1, v=ncol(mm)-1, col=1))
rasterVis::levelplot
, raster
, and latticeExtra
:
library(rasterVis)
library(latticeExtra)
levelplot(raster(mm), col.regions=c('white', 'black'),
margin=FALSE, colorkey=FALSE) +
layer(panel.grid(h=nrow(mm)-1, v=ncol(mm)-1, col=1))
sp::spplot
, raster
, and latticeExtra
:
library(raster)
library(latticeExtra)
spplot(raster(mm), colorkey=FALSE, col.regions=c('white', 'black')) +
layer(panel.grid(h=nrow(mm)-1, v=ncol(mm)-1, col=1))
raster
It can be a bit fiddly to set the graphics device's dimensions such that raster
doesn't plot additional (partial) cells outside the intended x and y limits. When using this approach, if the goal is to export to e.g. png, I plot to windows
/x11
/quartz
first and resize the window until the plotted area is as I'd intended, then query the device dimensions with dev.size()
and use these values to determine the dimension ratio for plotting to png
.
plot(raster(mm), legend=FALSE, col=c('white', 'black'))
abline(h=seq(0, 1, len=nrow(mm) + 1),
v=seq(0, 1, len=ncol(mm) + 1))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With