geom_tile() borders

4,184 views
Skip to first unread message

swright393

unread,
Feb 3, 2015, 11:45:44 AM2/3/15
to ggp...@googlegroups.com
Dear all:

I am trying to use geom_tile() as a simple binary indicator.  (For example, which published papers have measurements for which covariates).   The goal output would be tiles where the values is YES which have a border all around each tile, to match historical output of the same data.  And empty space otherwise.  

geom_tile works well, but the border (set by color) has the border of the lower or righthand tile (if empty) overwrites the border of the neighboring tile, making an incomplete border.  

Sample code:

library(ggplot2)

data_example<-data.frame(pub=rep(c("pub1","pub2","pub3","pub4","pub5"),5), measure=rep(c("age","sex","weight","smoking","alcohol"), 5, each=5), used=as.factor(rbinom(25, 1, 0.5))) 

ggplot(data_example, aes(y=pub, x=measure), color="black")+
  geom_tile(aes(fill=used,color=used))+
  theme(legend.position="none")+
  scale_fill_manual(values=c("white","gray70"))+scale_color_manual(values=c("00000000","black"))

 # Note that here I have tried to set the alpha of the color to 0 to make it transparent, but appears that alpha (as is usual) doesn't control the transparency of "color" when the object also has a fill.  There have been various other things tried (order of variables, etc).  

Any suggestions?  I don't see that layers would help as it would have the same issue.  Much appreciated,

Seth

Ista Zahn

unread,
Feb 3, 2015, 2:57:17 PM2/3/15
to swright393, ggplot2
My first thought was

library(scales)
ggplot(data_example, aes(y=pub, x=measure))+
geom_tile(aes(fill=used,color=used))+
theme(legend.position="none")+
scale_fill_manual(values=c("white","gray70"))+
scale_color_manual(values=c(alpha("00000000", 0) ,"black"))

but that doesn't quite work because the borders are still partially
obscured by the white tiles. I guess you will have to do something
ugly, like

ggplot(data_example, aes(y=pub, x=measure), color="black")+
geom_tile(aes(fill=used,color=used), size = 0, data =
subset(data_example, used == 0))+
geom_tile(aes(fill=used,color=used), size = 1, data =
subset(data_example, used == 1))+
theme(legend.position="none")+
scale_fill_manual(values=c("white","gray70"))+
scale_color_manual(values=c(alpha("00000000", 0) ,"black"))

Best,
Ista
> --
> --
> You received this message because you are subscribed to the ggplot2 mailing
> list.
> Please provide a reproducible example:
> https://github.com/hadley/devtools/wiki/Reproducibility
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ggplot2" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ggplot2+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

swright393

unread,
Feb 3, 2015, 3:56:16 PM2/3/15
to ggp...@googlegroups.com, swrig...@gmail.com
Thanks so much Ista.  Your second solution is perfect.   I was having cognitive blindness: but just because geom_tile() is usually used as a heatmap, and usually has a value plotted for every x,y combination, doesn't mean it HAS to have a value plotted for each x,y.  It's OK to let the background show through.
 

With your suggestion, for future reference in case anyone else looks for this:  here is my version of the final code.  It makes the background panel white, and gets rid of the unnecessary aes and color specifications, since there is only one fixed fill and one fixed color.  

ggplot(dataframe[dataframe$used=="1", ], aes(y=pub, x=measure))+
  geom_tile(fill="gray70",color="black")+
  theme(legend.position="none",panel.background = element_rect(fill = "white", colour = "white"))

Incidentally, I recall seeing a discussion where someone wanted a gradient fill on some parts of a heatmap, but a fixed color on the rest, depending on the value of a binary variable.  Hadley appropriately pointed out that there was no scale that would have a specific value for a categorical AND a gradient for a continuous, so it couldn't be handled with a scale() option.   If I recall it correctly, making parts of the heatmap background show through like this might be a potential solution (i.e. eliminate certain points, and color the background appropriately to show through). 

--Seth
Reply all
Reply to author
Forward
0 new messages