ggplot2:修复因子级别的颜色

时间:2017-04-16 17:34:55

标签: r ggplot2 colors

我正在开展一个更大的项目,我正在ggplot2中创建几个图。这些图涉及绘制几个不同类别的几种不同结果(想想:国家,物种,类型)。我想完全修复离散类型到颜色的映射,使得Type = A始终显示为红色,Type = B始终显示为蓝色,依此类推所有绘图,而不管其他因素是什么。我知道scale_fill_manual()我可以手动提供颜色值,然后使用drop = FALSE来帮助处理未使用的因子级别。但是,我发现这非常麻烦,因为每个绘图都需要一些手动工作来处理以正确方式排序因子,排序颜色值以匹配因子排序,丢弃未使用的水平等。

我正在寻找的是一种可以将一次和全局因子水平映射到特定颜色(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")

4 个答案:

答案 0 :(得分:11)

您可以制作自定义绘图功能(包括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)

答案 1 :(得分:11)

如果您愿意,可以定义自己的自定义比例。如果您查看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()

答案 2 :(得分:1)

确保首先将该列转换为Factor,然后创建一个变量来存储每个因子的颜色值...

df$color <- as.factor(df$color, levels = c(1, 0))
cbPallete <- c("1"= "green", "0"="red")

ggplot(data = df) + geom_bar(x = df$x, 
                             y = df$y,
                             fill = df$color) +
scale_fill_manual(values = cbPallete)

答案 3 :(得分:0)

另一种选择是通过定义如下所示的默认色标来将drop = F设置为默认值:

scale_colour_discrete <- function(...)
  scale_colour_manual(..., drop = F)
scale_fill_discrete <- function(...)
  scale_fill_manual(..., drop = F)

这样,颜色在不同因素下始终保持一致。