0

I have a simple matrix like this

 >df
           School1  School2 School3
 Program1        1        1       1
 Program2        1        0       1 
 Program3        1        1       0

The number 1 indicates that the school receivied the program and the number zero, no receivied. I would like to plot a simple square like the a cheesboard (black for 1 and white for 0). First I melt my df

df<- melt(df)

head(df)
         X1       X2 value
1 Program 1 School 1     1
2 Program 2 School 1     1
3 Program 3 School 1     1
4 Program 1 School 2     1
5 Program 2 School 2     0
6 Program 3 School 2     0

names(df)[1]<- "Var1"
names(df)[2]<- "Var2"

Now, I create my board

ggplot(df, aes(x=Var2, y=Var1, fill=value)) + geom_tile() +
theme(panel.background = element_blank(),
      #panel.grid.major = element_line(colour = "orange", size=2),
      panel.grid.minor = element_line(colour = "gray" , size = 3)) 

Which produces the following pictureenter image description here

But I would like to do somtehings:

1.- add a gray grid over the plot indicating the separation of each square

2.- manipulate the color square(black and white)

3.- manipulate the size of the labels on the axes (Program 1, Program 2, ... School 1, School 2,...) and its inclination(like las = 2 in barplot)

4.- Edit the bar legend (Yes with a black little square and No with a white little square)

5.- Exclude the names axes (Var1 and Var )

MAOC
  • 625
  • 2
  • 8
  • 26
  • 1
    Note you can just use `image(df, col=c('black', 'white'))` on your original data frame, no need to use melt etc. – nico Sep 13 '15 at 23:26
  • 2
    did you search? http://stackoverflow.com/questions/28035831/how-to-build-a-crossword-like-plot-for-a-boolean-matrix – rawr Sep 14 '15 at 00:24

2 Answers2

4
library(ggplot2)

dat <- read.table(text="Program School1  School2 School3
 Program1        1        1       1
 Program2        1        0       1 
 Program3        1        1       0", header=TRUE, stringsAsFactors=FALSE)

dat_long <- reshape2::melt(dat)

# discrete vs continuous
dat_long$value <- factor(dat_long$value)

gg <- ggplot(dat_long)

# fill + legend, gray border
gg <- gg + geom_tile(aes(x=Program, y=variable, fill=value), color="#7f7f7f")

# custom fill colors
gg <- gg + scale_fill_manual(values=c("white", "black"))

# squares
gg <- gg + coord_equal()

# no labels
gg <- gg + labs(x=NULL, y=NULL)

# remove some chart junk
gg <- gg + theme_bw()
gg <- gg + theme(panel.grid=element_blank())
gg <- gg + theme(panel.border=element_blank())
gg

enter image description here

Swap program vs school as needed.

hrbrmstr
  • 77,368
  • 11
  • 139
  • 205
1

I tried to do this with base graphics (using heatmap()) and with the (underappreciated) image method. Neither was as easy as I would have liked.

Construct data:

dat <- matrix(c(1,1,1,1,0,1,1,1,0),byrow=TRUE,nrow=3,
              dimnames=list(paste0("Program",1:3),
                            paste0("School",1:3)))

Using Matrix

Unfortunately the image method (which is otherwise very nice) doesn't handle dimnames, so we have to hack around a bit.

library(Matrix)
library(lattice)
## getMethod("image",sig="dgTMatrix")  ## examine the function

Hack tick mark label settings to make them transparent:

tp.orig <- trellis.par.get()
tp2 <- tp.orig
tp2$axis.text$alpha  <- 0
## optionally add space for vertical labels?
##  tp2$layout.heights$bottom.padding <- 20  
trellis.par.set(tp2)  

image(Matrix(dat),useRaster=TRUE,sub="",xlab="",ylab="")

Add labels and grid:

trellis.focus("panel",1,1,highlight=FALSE,clip.off=TRUE)
trellis.par.set(tp.orig)
dims <- dim(dat)
dn <- dimnames(dat)
panel.axis(side="bottom",at=1:dims[2],labels=dn[[2]],outside=TRUE,rot=0)
panel.axis(side="left",at=1:dims[1],labels=dn[[1]],outside=TRUE)
panel.grid(h=2,v=2)

Using base graphics

Actually I ended up using gplots. Could still use some tweaking.

library("gplots")
par(oma=c(5,0,0,5))
heatmap.2(dat,dendrogram="none",col=c("gray","white"),
          key=FALSE,trace="both",tracecol="black",
          hline=numeric(0),vline=numeric(0))
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453