小伙伴发来这个文章中的图,想要实现类似的图,用变量给axis text上色,并生成legend:

这个可以说ggplot2是不支持的,aes映射不会被应用于axis上,而theme也不支持aes映射,你只能自己手动搞个color vector传给theme来上色,但这无法生成legend。

我只能打开脑洞,legend借助于额外的图层来生成,但这个额外的图层又不是我们想要在图形上展示的,这又是个无米之炊,我能想到的就是让图层透明,实际有,但你看不到,当然这样自动生成的legend也会看不到,但legend可以后面再修改,于是这不支持的事情,就通过变通变得可能:

require(ggplot2)

set.seed(2017-07-04)
d <- data.frame(x = letters[1:5], y = rnorm(5), 
		group = sample(c("Control", "Treatment"), 5, replace=TRUE),
		type = sample(LETTERS[1:2], 5, replace=TRUE)
)

p <- ggplot(d, aes(x,y)) + 
	geom_col(aes(fill=group))

这个代码很好懂,画一个柱状图,按group上色。

devtools::install_github(“guangchuangyu/yyplot”) ## to install yyplot

为了实现文章开头说的功能,我在yyplot里写了set_axis_text_color函数:

  • p:你画的ggplot图
  • colors:上什么色
  • mapping:用什么变量来生成legend
  • fake_aes: 用什么假aes来生成legend,这个假aes是你传入的p里没用过的
  • axis:给哪个axis上色,可以是’x’,‘y’或’xy’

    require(yyplot)
    
    cols <- c(A = "red", B = "blue")
    p2 <- set_axis_text_color(p, colors=cols,
    		mapping=~type, fake_aes='color', axis="x")
    

最后再把输入的表格也画在图上,用grid::tableGrob来画,用ggimage::geom_subview来嵌图,三张图组合起来:

require(ggimage)
require(gridExtra)

p3 <- p2 + 
	geom_subview(tableGrob(d, rows=NULL), 
				 x=4, y=0.95)

grid.arrange(grid.arrange(p, p2, ncol=1), 
	p3, ncol=2)

这个功能曾经在《ggplot2作图5招:《R入门25个菜谱》中所有图片的ggplot2版本》预告过,和《Use ggplot2》这两篇文章是ggplot2入门的好教材。

电梯