使用TableGrob更改单元格的文本颜色 [英] Change text color for cells using TableGrob

查看:118
本文介绍了使用TableGrob更改单元格的文本颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用tableGrob和ggplot2时,是否可以单独更改单元格文本的颜色?

Is there a way to individually change the color of the text of a cell when using tableGrob and ggplot2?

例如,在下面的代码中,如果具有1的单元格可以是蓝色,而具有2的单元格可以是红色(3:8都是黑色),那将是很好的.

For instance in the code below it'd be great if the cell with 1 could be blue and the cell with 2 could be red, with 3:8 all black.

library(ggplot2)
library(grid)

mytable = as.table(matrix(c("1","2","3","4","5","6","7","8"),ncol=2,byrow=TRUE))
mytable = tableGrob(mytable,gpar.coretext = gpar(col = "black", cex = 1))
mydf = data.frame(x = 1:10,y = 1:10)

ggplot( mydf, aes(x, y)) + annotation_custom(mytable)

推荐答案

令我非常失望的是,这似乎并不容易. tableGrob函数调用makeTableGrobs来布局网格对象并返回完全计算的gTree结构.如果您可以拦截,更改某些属性并继续,那将是很好的.不幸的是,绘制是使用gridExtra:::drawDetails.table完成的,并且该函数坚持要再次调用makeTableGrobs,从根本上消除了进行任何自定义的机会.

Much to my disappointment, this does not seem to be easy. The tableGrob function calls makeTableGrobs to layout the grid object and returns a fully calculated gTree structure. It would be nice if you could intercept that, change some properties, and continue on; unfortunately the drawing gets done with gridExtra:::drawDetails.table and that function insists on calling makeTableGrobs again, essentially killing any opportunity for customization.

但这不是不可能的.基本上,我们可以创建自己的drawDetails.table版本,该版本不进行重新处理.这是gridExtra中的函数,在开头添加了一个if语句.

But it's not impossible. Basically we can create our own version of drawDetails.table that doesn't do the reprocessing. Here's the function from gridExtra with one added if statement at the beginning.

drawDetails.table <- function (x, recording = TRUE) 
{
    lg <- if(!is.null(x$lg)) {
        x$lg
    } else {
        with(x, gridExtra:::makeTableGrobs(as.character(as.matrix(d)), 
        rows, cols, NROW(d), NCOL(d), parse, row.just = row.just, 
        col.just = col.just, core.just = core.just, equal.width = equal.width, 
        equal.height = equal.height, gpar.coretext = gpar.coretext, 
        gpar.coltext = gpar.coltext, gpar.rowtext = gpar.rowtext, 
        h.odd.alpha = h.odd.alpha, h.even.alpha = h.even.alpha, 
        v.odd.alpha = v.odd.alpha, v.even.alpha = v.even.alpha, 
        gpar.corefill = gpar.corefill, gpar.rowfill = gpar.rowfill, 
        gpar.colfill = gpar.colfill))
    }
    widthsv <- convertUnit(lg$widths + x$padding.h, "mm", valueOnly = TRUE)
    heightsv <- convertUnit(lg$heights + x$padding.v, "mm", valueOnly = TRUE)
    widthsv[1] <- widthsv[1] * as.numeric(x$show.rownames)
    widths <- unit(widthsv, "mm")
    heightsv[1] <- heightsv[1] * as.numeric(x$show.colnames)
    heights <- unit(heightsv, "mm")
    cells = viewport(name = "table.cells", layout = grid.layout(lg$nrow + 
        1, lg$ncol + 1, widths = widths, heights = heights))
    pushViewport(cells)
    tg <- gridExtra:::arrangeTableGrobs(lg$lgt, lg$lgf, lg$nrow, lg$ncol, 
        lg$widths, lg$heights, show.colnames = x$show.colnames, 
        show.rownames = x$show.rownames, padding.h = x$padding.h, 
        padding.v = x$padding.v, separator = x$separator, show.box = x$show.box, 
        show.vlines = x$show.vlines, show.hlines = x$show.hlines, 
        show.namesep = x$show.namesep, show.csep = x$show.csep, 
        show.rsep = x$show.rsep)
    upViewport()
}

通过在全局环境中定义此功能,它将优先于gridExtra中的功能.这将使我们能够在绘制表格之前自定义表格,而不必重置更改.这是根据您的要求更改前两行中值的颜色的代码.

By defining this function in the global environment, it will take precedence over the one in gridExtra. This will allow us to customize the table before it gets drawn and not have our changes get reset. Here's code to change the colors of the values in the first two rows as you requested.

mytable = as.table(matrix(c("1","2","3","4","5","6","7","8"),ncol=2,byrow=TRUE))
mytable = tableGrob(mytable,gpar.coretext = gpar(col = "black", cex = 1))

mytable$lg$lgt[[7]]$gp$col <- "red"
mytable$lg$lgt[[12]]$gp$col <- "blue"

mydf = data.frame(x = 1:10,y = 1:10)
ggplot( mydf, aes(x, y)) + annotation_custom(mytable)

然后就产生了这个情节.

And that produces this plot.

所以语法有点含糊,但让我用这一行来解释

So the syntax is a bit cryptic, but let me explain with this line

mytable$lg$lgt[[7]]$gp$col <- "red"

mytable对象实际上只是一个修饰列表.它具有一个lg项,该项是根据makeTableGrobs计算得出的,并且其中包含所有原始的grid元素.在其下的lgt元素是具有所有文本层的另一个列表.对于此表,lgt具有15个元素.表格中的每个方块一个,以左上角的空"开头.它们按从上到下,从左到右的顺序排列,因此列表中具有1的单元格为[[7]].如果运行str(mytable$lg$lgt[[7]]),则可以看到组成该文本grob的属性.您还会注意到gp的一部分,您可以在其中通过col元素设置文本的颜色.因此,我们将其从默认的黑色"更改为所需的红色".

The mytable object is really just a decorated list. It has an lg item which is what's calculated from makeTableGrobs and has all the raw grid elements inside. The lgt element under that is another list that has all the text layers. For this table, lgt has 15 elements. One for each square in the table starting with the "empty" one in the upper left. They go in order top-to-bottom, left-to-right, so the cell with 1 is [[7]] in the list. If you run str(mytable$lg$lgt[[7]]) you can see the properties that make up that text grob. You will also notice a section for gp where you can set the color of the text via the col element. So we change it from the default "black" to the desired "red".

我们正在做的事情不是官方API的一部分,因此应将其视为黑客行为,因此对于所涉及的库(ggplot2gridgridExtra)中的将来更改可能是脆弱的.但是希望这至少可以帮助您开始自定义表格.

What we are doing isn't part of the official API so it should be considered a hack and as such may be fragile to future changes in the libraries involved (ggplot2,grid,gridExtra). But hopefully this will at least help you get started in customizing your table.

这篇关于使用TableGrob更改单元格的文本颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆