2017-08-23 38 views
4

scales參數設置爲"free"時,我似乎無法在刻面圖上正確着色軸文本。請看下面的數據集:ggplot2:在刻面圖上着色軸文本

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

我們可以繪製在單一方面的數據,突出了字母d,O,T作爲如下:

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)) 

使刻面的情節使用默認scales = "fixed"正確亮點D,O,T在兩個方面。

g + facet_wrap(~V3) 

enter image description here

然而,scales參數切換到"free"導致意外的行爲,只有d和Q突出。

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

enter image description here

我的問題:這是一個錯誤還是我需要以某種方式修改我的v定義免費開戶規模。如果它是一個bug,是否有人知道一個解決方法來突出顯示每個(自由縮放的)方面中的特定軸文本?


編輯:自己的答案移動到答案,正如Henrik所建議的。

+1

爲什麼不張貼你的答案正確的答案?你也許還會在「遇到潛在的黑客攻擊」部分進行擴展 - 從其他答案中,我意識到在grobs之間進行定向可能相當棘手...... Cheers – Henrik

+0

謝謝Henrik。偉大的建議。我發佈了一個答案,擴展瞭如何瀏覽grob層次結構。 –

+0

優秀!非常感謝。加上馬上! – Henrik

回答

3

我不認爲這是一個錯誤。問題是v這裏基本上是一串字符,長度爲26,它定義了x軸上前26個斷點的顏色。當x軸恰好有26個斷點時,好吧&好;當它小於那個值時(這是你設置scales="free"的情況),它只是在每個軸的開始處重新開始。 Q在這裏是紅色的,因爲它在第二個圖中位於第四個位置,儘管在第一個圖中v[4]的紅色是針對D的。

根據我試過的&在這裏閱讀,不能將美學映射到控制ggplot中軸文本外觀的theme()

通過使用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

2

通過與劇情相關的圖形對象(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. 如果格羅是gtable類型(如gt上面),訪問進入表格的個人數據庫可以通過$grobs完成。
  2. 如果grob不是gtable類型,則可以通過$children訪問其子孩子的grobs。

看上面的gtable,我們觀察到梯形6和7分別對應於刻面1和2的底部軸線。每個軸grobs的是absoluteGrob類型的,所以使用上述兩個規則,我們可以檢查他們的喜歡這件事做什麼:

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

注意到第二個孩子是gtable,我們可以繼續降直到我們到達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.Lin的解決方案中所建議的)。

因此,將這些顏色設置設置爲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

+1

'''grid_draw()'''現在是'''grid.draw()'''。 – TrigonaMinima

+0

答覆已更新。謝謝! –