2017-04-16 162 views
2

我正在爲其中一個較大的項目工作,我在ggplot2中創建了幾個圖。這些情節關心繪製幾個不同的謹慎類別(想想:國家,物種,類型)的幾個不同的結果。我想完全修復離散類型到顏色的映射,使Type = A始終顯示爲紅色,Type = B始終顯示爲藍色,所有繪圖都以不管其他因素如何顯示。我知道scale_fill_manual(),我可以手動提供顏色值,然後使用drop = FALSE,這有助於處理未使用的因子水平。但是,我發現這非常麻煩,因爲每個情節都需要一些手動工作來處理以正確的方式排序因素,對顏色值進行排序以匹配因子排序,降低未使用的級別等。ggplot2:修復因子水平的顏色

我在尋找的是我可以將一次和全局因子水平映射到特定顏色(A =綠色,B =藍色,C =紅色,...),然後只需繪製任何我喜歡的圖和ggplot選擇正確的顏色。

下面是一些代碼來說明這一點。

# Full set with 4 categories 
df1 <- data.frame(Value = c(40, 20, 10, 60), 
        Type = c("A", "B", "C", "D")) 

ggplot(df1, aes(x = Type, y = Value, fill = Type)) + geom_bar(stat = "identity") 


# Colors change complete because only 3 factor levels are present 
df2 <- data.frame(Value = c(40, 20, 60), 
        Type = c("A", "B", "D")) 

ggplot(df2, aes(x = Type, y = Value, fill = Type)) + geom_bar(stat = "identity") 


# Colors change because factor is sorted differently 
df3 <- data.frame(Value = c(40, 20, 10, 60), 
        Type = c("A", "B", "C", "D")) 
df3$Type <- factor(df3$Type, levels = c("D", "C", "B", "A"), ordered = TRUE) 

ggplot(df3, aes(x = Type, y = Value, fill = Type)) + geom_bar(stat = "identity") 

回答

3

你可以做一個自定義的繪圖功能(包括scale_fill_manual和合理的默認顏色),以避免重複代碼:

library(ggplot2) 
custom_plot <- function(.data, 
    colours = c("A" = "green", "B" = "blue", "C" = "red", "D" = "grey")) { 
    ggplot(.data, aes(x=Type, y=Value, fill= Type)) + geom_bar(stat="identity") + 
    scale_fill_manual(values = colours) 
} 

df1 <- data.frame(Value=c(40, 20, 10, 60), Type=c("A", "B", "C", "D")) 
df2 <- data.frame(Value=c(40, 20, 60), Type=c("A", "B", "D")) 
df3 <- data.frame(Value=c(40, 20, 10, 60), Type=c("A", "B", "C", "D")) 
df3$Type <- factor(df3$Type, levels=c("D", "C", "B", "A"), ordered=TRUE) 

custom_plot(df1) 
custom_plot(df2) 
custom_plot(df3) 
+0

AH!所以scale_fill_manual()*可以*處理命名向量!這正是我所期待的。謝謝Kristoffer。 – Chris

2

你可以定義自己的規模,如果你喜歡。如果你看一下源scale_fill_manual

scale_fill_manual 
#> function (..., values) 
#> { 
#>  manual_scale("fill", values, ...) 
#> } 
#> <environment: namespace:ggplot2> 

它實際上很簡單:

library(ggplot2) 

scale_fill_chris <- function(...){ 
    ggplot2:::manual_scale('fill', 
          values = setNames(c('green', 'blue', 'red', 'orange'), 
              LETTERS[1:4]), 
          ...) 
} 

df1 <- data.frame(Value = c(40, 20, 10, 60), 
        Type = c("A", "B", "C", "D")) 

ggplot(df1, aes(x = Type, y = Value, fill = Type)) + 
    geom_col() + 
    scale_fill_chris() 

df2 <- data.frame(Value = c(40, 20, 60), 
        Type = c("A", "B", "D")) 

ggplot(df2, aes(x = Type, y = Value, fill = Type)) + 
    geom_col() + 
    scale_fill_chris() 

df3 <- data.frame(Value = c(40, 20, 10, 60), 
        Type = c("A", "B", "C", "D")) 
df3$Type <- factor(df3$Type, levels = c("D", "C", "B", "A"), ordered = TRUE) 

ggplot(df3, aes(x = Type, y = Value, fill = Type)) + 
    geom_col() + 
    scale_fill_chris()