2015-06-30 323 views
4

是否可以將圖形的x軸上的值跟隨ggplot barplot的fill圖例拆分?ggplot條形圖 - 沿x軸系數分割填充圖例

例如使用這樣的數據:

library(ggplot2) 
data <- data.frame(val=c(2,4,5,6,7,8,9),var1=c("A","A","A","B","B","C","C"), 
     var2=sample(LETTERS[1:7])) 
ggplot(data,aes(x=factor(var1),y=val,fill=var2))+geom_bar(stat="identity") 

我碰到下面的情節: enter image description here

我想有這樣的事情,以使其更容易查找每個fill顏色對應:

enter image description here

+0

你可以看看[**這個答案**](http://stackoverflow.com/questions/19568901/multiple-colour-scales-in-one-stacked-酒吧情節使用-ggplot/19573826#19573826)。 [** This **](http://stackoverflow.com/questions/20474465/using-different-scales-as-fill-based-on-factor/20479882#20479882)也有關係。我相信那裏有更多。 – Henrik

+1

正如我在其中一個答案中寫的那樣。 「'ggplot'中的基本設計是每個」合理「的規模,因此需要各種程度醜陋的變通方法,通常包括創建一個或多個繪圖對象,操作對象的各種組件,以及然後從被操縱的物體上產生一個新的情節。「 – Henrik

回答

1

解決方案的替代方案在評論中的鏈接。該解決方案假定數據以彙總形式提供,並且每個var2類別都出現在var1的一個類別中,並且只出現在一個類別中。也就是說,圖例中的密鑰數量(及其順序)是正確的。所有需要做的事情就是將空間插入適當的鍵和放入這些空間的文本之間。它從初始繪圖或其構建數據中獲取構建繪圖所需的信息。

library(ggplot2) 
library(gtable) 
library(grid) 

set.seed(1234) 
data <- data.frame(val = c(2,4,5,6,7,8,9), 
     var1 = c("A","A","A","B","B","C","C"), 
     var2 = sample(LETTERS[1:7])) 

# Sort levels of var2 
data$var2 = factor(data$var2, labels = data$var2, levels = data$var2) 

p = ggplot(data, aes(x = factor(var1), y = val, fill = var2)) + 
    geom_bar(stat = "identity") 

# Get the ggplot grob 
g = ggplotGrob(p) 

# Get the legend 
leg = g$grobs[[which(g$layout$name == "guide-box")]]$grobs[[1]] 

# Get the labels from the ggplot build data 
gt = ggplot_build(p) 
labels = rev(gt$layout$panel_ranges[[1]]$x.labels) 

## Positions of the labels 
# Get the number of keys within each label from the ggplot build data 
gt$data[[1]]$x 
N = as.vector(table(gt$data[[1]]$x)) 
N = N[-length(N)] 
# Get the positions of the labels in the legend gtable 
pos = rev(cumsum(N)) + 3 
pos = c(pos, 3) 

# Add rows to the legend gtable, and add the labels to the new rows 
for(i in seq_along(pos)){ 
leg = gtable_add_rows(leg, unit(1.5, "lines"), pos = pos[i]) 
leg = gtable_add_grob(leg, textGrob(labels[i], y = 0.1, just = "bottom"), 
     t = pos[i] + 1, l = 2) 
} 

# Put the legend back into the plot 
g$grobs[[which(g$layout$name == "guide-box")]]$grobs[[1]] = leg 

# Draw it 
grid.newpage() 
grid.draw(g) 

enter image description here