ggplot2:修复因子水平的颜色
问题描述:
我正在为其中一个较大的项目工作,我在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")
答
你可以做一个自定义的绘图功能(包括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)
答
你可以定义自己的规模,如果你喜欢。如果你看一下源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()
AH!所以scale_fill_manual()*可以*处理命名向量!这正是我所期待的。谢谢Kristoffer。 – Chris