在 ggplot 函数中通过编程方式指定 scale_fill_manual 的颜色

5
我想根据特定列中的值为ggplot2分面绘图着色。使用我之前提出的问题的答案,我已经成功地整合了所需的内容。@joran对这个问题的回答特别有帮助,因为它阐述了创建一个单独的数据框传递给ggplot的技巧。
所有这些都很好地运作,产生了以下图像输出: facets coloured by region 以下是生成上述图的代码:
# User-defined variables go here

list_of_names <- c('aa','bb','cc','dd','ee','ff')
list_of_regions <- c('europe','north america','europe','asia','asia','japan')

# Libraries

require(ggplot2)
require(reshape)

# Create random data with meaningless column names
set.seed(123)
myrows <- 30
mydf <- data.frame(date = seq(as.Date('2012-01-01'), by = "day", length.out = myrows),
                   aa = runif(myrows, min=1, max=2),
                   bb = runif(myrows, min=1, max=2),
                   cc = runif(myrows, min=1, max=2),
                   dd = runif(myrows, min=1, max=2),
                   ee = runif(myrows, min=1, max=2),
                   ff = runif(myrows, min=1, max=2))

# Transform data frame from wide to long

mydf <- melt(mydf, id = c('date'))
mydf$region <- as.character("unassigned")

# Assign regional label

for (ii in seq_along(mydf$date)) {
    for (jj in seq_along(list_of_names)) {
        if(as.character(mydf[ii,2]) == list_of_names[jj]) {mydf$region[ii] <- as.character(list_of_regions[jj])}
    }
}

# Create data frame to pass to ggplot for facet colours
mysubset <- unique(mydf[,c('variable','region')])
mysubset$value <- median(mydf$value) # a dummy value but one within the range used in the data frame
mysubset$date <- as.Date(mydf$date[1]) # a dummy date within the range used

# ... And plot
p1 <- ggplot(mydf, aes(y = value, x = date, group = variable)) +
    geom_rect(data = mysubset, aes(fill = region), xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf, alpha = 0.3) +
    scale_fill_manual(values = c("japan" = "red", "north america" = "green", "asia" = "orange", "europe" = "blue")) +
    geom_line() +
    facet_wrap( ~ variable, ncol = 2)

print (p1)

我要翻译的内容是关于 IT 技术的,这个实际脚本将被用于许多包含不同数据系列的不同组,因此这个脚本将被重复多次,只有变量会改变。
这使得用户定义的元素清晰可编辑非常重要,这就是为什么 list_of_nameslist_of_regions 变量放在文件的开头的原因。(当然,最好不要改动脚本,而是把这些列表定义为外部文件或将它们作为参数传递给脚本。) 我尝试通过使用那两个 for 循环来分配区域来推广解决方案。我曾经试图用 apply 函数来获得更 R 本质化的解决方案,但是我无法让它工作,所以我放弃了并坚持使用我知道的东西。
然而,在我的代码中,scale_fill_manual 需要明确传递变量来定义填充颜色,例如 'europe' = 'blue'。这些变量将根据我正在处理的数据而变化,因此对于脚本的当前形式,我需要手动编辑每个数据系列组的 ggplot 部分。我知道这可能很耗时,并且我强烈怀疑它也很容易出错。
问题:理想情况下,我希望能够从先前声明的值列表 (在这种情况下是从 list_of_regions 匹配到先前声明的颜色列表) 中编程提取和定义所需的值,以供 scale_fill_manual 调用使用,但我想不到实现的方法。你有任何想法吗?

如果您有一个地区列表和一个颜色列表,那么这是可能的。颜色列表在哪里? - kohske
额,呃,还没有定义一个! 任意颜色列表对于一个例子来说已经足够了。 - SlowLearner
1个回答

5
这有帮助吗?
cols <- rainbow(nrow(mtcars))
mtcars$car <- rownames(mtcars)

ggplot(mtcars, aes(mpg, disp, colour = car)) + geom_point() +
  scale_colour_manual(limits = mtcars$car, values = cols) +
  guides(colour = guide_legend(ncol = 3))

enter image description here


谢谢@kohske ,v0.90兼容!只是想澄清一下,如果我想为每辆汽车指定颜色,我该怎么做?(抱歉-我曾说过任意颜色列表都可以。我应该说我不介意使用哪种颜色,但我想能够为每个项目定义颜色,例如每个车型。) - SlowLearner
然后根据您的喜好修改cols。重要的是在scale_colour_manuallimitsvalues的对应关系。 - kohske
听起来很简单。所以limits指定了项目,values指定了颜色,这样limits列表中的第一个项目就被分配到values列表中的第一个颜色,以此类推? - SlowLearner
没错。尝试使用 scale_colour_manual(limits = rev(mtcars$car), values = cols)。你可以在这里找到一些讨论:https://github.com/hadley/ggplot2/issues/501 - kohske

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接