ggplot2:在刻面图上着色轴文本

时间:2017-08-23 15:24:14

标签: r ggplot2 facet-wrap

FacebookSDK参数设置为scales时,我似乎无法在分面图上正确地为轴文本着色。请考虑以下数据集:

"free"

我们可以在单个面上绘制数据,突出显示字母D,O,T,如下所示:

library( ggplot2 )
X <- data.frame( V1 = LETTERS, V2 = runif( 26 ),
    V3 = rep( c("F1", "F2"), each = 13 ) )

使用默认v <- ifelse( X$V1 %in% c( "D", "O", "T" ), "red", "black" ) g <- ggplot( X, aes( x = V1, y = V2 ) ) + geom_point() + theme( axis.text.x = element_text( color = v ) ) 制作地图刻面正确地突出显示两个面上的D,O,T。

scales = "fixed"

enter image description here

但是,将g + facet_wrap( ~V3 ) 参数切换为scales会导致意外行为,其中只突出显示D和Q.

"free"

enter image description here

我的问题:这是一个错误还是我需要以某种方式修改我对g + facet_wrap( ~V3, scales = "free" ) 的定义以解释自由规模。如果它是一个错误,是否有人知道一个解决方法,以突出显示每个(自由缩放)方面的特定轴文本?

编辑:正如亨里克所建议的那样,自己的答案转移到了答案。

2 个答案:

答案 0 :(得分:6)

我不认为这是一个错误。问题是v这里基本上是一串字符,长度为26,它定义了x轴上前26个中断的颜色。当x轴完全有26个断点时,那么&amp;好;如果它小于那个(设置scales="free"时的情况),它只是在每个轴的开头重新启动。 Q在这里是红色的,因为它在第二个图中处于第四个位置,尽管在第一个图中v[4]的红色代表D。

基于我所尝试过的&amp;在这里阅读,可以将美学映射到theme(),它控制ggplot中轴文本的外观。

通过隐藏轴和放大器来破解解决方案是可能的。使用geom_text()代替模拟轴,因为后者确实接受从数据映射的美学。但它可能不是很优雅:

g2 <- ggplot(cbind(X, v), #add v to X
             aes(x = V1, y = V2)) + 
  geom_point() +
  # make space to accommodate the fake axis
  expand_limits(y = -0.05) +
  # create a strip of white background under the fake axis
  geom_rect(ymin = -5, ymax = 0, xmin = 0, xmax = nrow(X) + 1, fill = "white") +
  # fake axis layer, aligned below y = 0
  geom_text(aes(colour = v, label = V1), y = 0, vjust = 1.1) +
  # specify the font colours for fake axis
  scale_colour_manual(values = c("black", "red"), guide = F) +
  # hide the actual x-axis text / ticks
  theme(axis.text.x = element_blank(), axis.ticks.x = element_blank())

g2 + facet_wrap( ~V3, scales = "free" )

facet plot with fake axis

答案 1 :(得分:5)

在挖掘了与情节相关的图形对象(grobs)之后,我遇到了一个潜在的黑客来解决这个问题。虽然没有Z.Lin's solution那么优雅,但我想分享它用于教育目的。

我们首先用

检索grobs
gt <- ggplotGrob( g + facet_wrap( ~V3, scales = "free" ) )
## TableGrob (11 x 11) "layout": 20 grobs
##     z         cells        name                                  grob
## 1   0 ( 1-11, 1-11)  background       rect[plot.background..rect.105]
## 2   1 ( 7- 7, 4- 4)   panel-1-1               gTree[panel-1.gTree.17]
## 3   1 ( 7- 7, 8- 8)   panel-2-1               gTree[panel-2.gTree.30]
## 4   3 ( 5- 5, 4- 4)  axis-t-1-1                        zeroGrob[NULL]
## 5   3 ( 5- 5, 8- 8)  axis-t-2-1                        zeroGrob[NULL]
## 6   3 ( 8- 8, 4- 4)  axis-b-1-1    absoluteGrob[GRID.absoluteGrob.43]
## 7   3 ( 8- 8, 8- 8)  axis-b-2-1    absoluteGrob[GRID.absoluteGrob.50]
## 8   3 ( 7- 7, 7- 7)  axis-l-1-2    absoluteGrob[GRID.absoluteGrob.64]
## 9   3 ( 7- 7, 3- 3)  axis-l-1-1    absoluteGrob[GRID.absoluteGrob.57]
## 10  3 ( 7- 7, 9- 9)  axis-r-1-2                        zeroGrob[NULL]
## 11  3 ( 7- 7, 5- 5)  axis-r-1-1                        zeroGrob[NULL]
## 12  2 ( 6- 6, 4- 4) strip-t-1-1                         gtable[strip]
## 13  2 ( 6- 6, 8- 8) strip-t-2-1                         gtable[strip]
## 14  4 ( 4- 4, 4- 8)      xlab-t                        zeroGrob[NULL]
## 15  5 ( 9- 9, 4- 8)      xlab-b titleGrob[axis.title.x..titleGrob.33]
## 16  6 ( 7- 7, 2- 2)      ylab-l titleGrob[axis.title.y..titleGrob.36]
## 17  7 ( 7- 7,10-10)      ylab-r                        zeroGrob[NULL]
## 18  8 ( 3- 3, 4- 8)    subtitle zeroGrob[plot.subtitle..zeroGrob.102]
## 19  9 ( 2- 2, 4- 8)       title    zeroGrob[plot.title..zeroGrob.101]
## 20 10 (10-10, 4- 8)     caption  zeroGrob[plot.caption..zeroGrob.103]

Grobs是分层对象,遍历这些结构的一般规则分为两类:

  1. 如果grob的类型为gtable(上面为gt),则可以通过$grobs访问进入表格的各个grob。
  2. 如果grob不是gtable类型,则可以通过$children访问其子格林。
  3. 观察上面的gtable,我们观察到凹槽6和7分别对应于刻面1和2的底轴。这些轴grob中的每一个都是absoluteGrob类型,所以使用上面的两个规则,我们可以检查它们是由什么构成的:

    gt$grobs[[6]]$children
    ## (zeroGrob[axis.line.x..zeroGrob.40], gtable[axis]) 
    ##  and likewise for gt$grobs[[7]]$children
    

    注意到第二个孩子是gtable,我们可以继续降低grobs的层次结构,直到我们到达gt$grobs[[6]]$children[[2]]$grobs[[2]]$children[[1]],这是grob层次结构的一个叶子(它的$childrenNULL)并且对应于轴文本。让我们检查一下它的图形参数,可以通过$gp

    进行访问
    ## Double-check that we have the correct text object
    gt$grobs[[6]]$children[[2]]$grobs[[2]]$children[[1]]$label
    ## [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M"
    
    ## Display the summary of graphical parameters
    str( gt$grobs[[6]]$children[[2]]$grobs[[2]]$children[[1]]$gp )
    ## List of 5
    ##  $ fontsize  : num 8.8
    ##  $ col       : chr [1:26] "black" "black" "black" "red" ...
    ##  $ fontfamily: chr ""
    ##  $ lineheight: num 0.9
    ##  $ font      : Named int 1
    ##   ..- attr(*, "names")= chr "plain"
    ##  - attr(*, "class")= chr "gpar"
    

    请注意,col属性的长度为26,并且与问题中的v变量完全对应。如果我们查看第二个方面的底部轴(gt$grobs[[7]]$...),我们会看到同样使用col值,导致两个方面的轴文本着色相同(如Z中所示) 。林的解决方案)。

    因此,将这些颜色设置仅设置为v“手动”的相应部分,可以让我们修改原始图并获得所需的结果。

    gt$grobs[[6]]$children[[2]]$grobs[[2]]$children[[1]]$gp$col <- v[1:13]
    gt$grobs[[7]]$children[[2]]$grobs[[2]]$children[[1]]$gp$col <- v[14:26]
    grid::grid.draw( gt )
    

    enter image description here