以编程方式指定scale_fill_manual ggplot调用中的颜色 [英] Programmatically specifying colours in scale_fill_manual ggplot call

查看:341
本文介绍了以编程方式指定scale_fill_manual ggplot调用中的颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据特定列中给定的值为ggplot2 facet图的背景着色。使用前面提到的问题的答案,我已经问过,我能够将我需要的东西拼凑在一起。 @ joran回答这个问题特别有用,因为它说明了这种技术创建一个单独的数据框传递给ggplot。



这一切都很好用,给出了如下图所示的输出:



以下是我用于生成上述代码的代码plot:

 #用户定义的变量在这里

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

#图书馆

要求(ggplot2)
要求(重塑)

#创建无意义的数据列名
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))

#将数据帧从宽转换为长

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

#指定区域标签
$ b $ for(ii in seq_along(mydf $ date)){
for(jj in seq_along(list_of_names)){
if(as.character(mydf [ii,2] )==列表名称[jj]){mydf $ region [ii]< - as.character(list_of_regions [jj])}
}
}

#创建数据框(mydf [,c('variable','region')])
mysubset $ value< - median(mydf $ value)#a假娃娃lue,但在数据框中使用的范围之一
mysubset $ date< - as.Date(mydf $ date [1])#在所使用的范围

#内的虚拟日期。 ..和绘图
p1 < - ggplot(mydf,aes(y = value,x = date,group = variable))+
geom_rect(data = mysubset,aes(fill = region) = -Inf,xmax = Inf,ymin = -Inf,ymax = Inf,alpha = 0.3)+
scale_fill_manual(values = c(japan=red,north america=green ())+
geom_line()+
facet_wrap(〜variable,ncol = 2)

print(p1)

我正在使用的真实世界脚本旨在用于许多不同的包含多个不同的数据系列,所以这个脚本将被重复多次,只有变量发生变化。



这使用户定义的元素清晰易于编辑非常重要,这就是为什么 list_of_names list_of_regions 变量放在文件的开头。 (当然,根本不需要更改脚本,而是将这些列表定义为外部文件或将它们作为参数传递给脚本)。我试图通过使用这两个 for 循环来分配区域。我做了一段时间试图用 apply 函数来获得更加以R为中心的解决方案,但无法实现它,所以我放弃了并坚持我所知道的。

然而,在我的代码中, scale_fill_manual 调用需要显式传递变量来定义填充颜色,例如'europe'='蓝色'。这些变量会根据我正在处理的数据而有所不同,所以对于当前形式的脚本,我需要为每组数据系列手动编辑脚本的ggplot部分。我知道这会很费时,而且我强烈怀疑它也会很容易出错。

Q。理想情况下,我希望能够以编程方式从先前声明的值列表中提取和定义 scale_fill_manual 调用所需的值(本例中为 list_of_regions )与以前声明的颜色列表相匹配,但我想不出一种方法来实现这一点。您有什么想法吗?

解决方案

这有帮助吗?

  cols < -  rainbow(nrow(mtcars))
mtcars $ car <-rownames(mtcars)

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


I want to colour the backgrounds of a ggplot2 facet plot depending on the value given in a particular column. Using answers to previous questions I have already asked, I was able to piece what I needed together. @joran's answer to this question was particularly useful as it illustrates the technique of creating a separate data frame to pass to ggplot.

This all works nicely enough, giving the output shown in the following image:

Here is the code I used to generate the above plot:

# 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)

The real-world script towards which I am working is intended to be used for many different groups containing many different data series, so this script will be duplicated many times, with only the variables changing.

This makes it important to have the user-defined elements clearly accessible for editing, which is why the list_of_names and list_of_regions variables are put right at the start of the file. (Of course, it would be better not to need to change the script at all but rather define these lists as external files or pass them to the script as arguments.) I tried to generalise the solution by using those two for loops to assign the regions. I did fiddle around for a while trying to get a more R-centric solution using apply functions but couldn't get it to work so I gave up and stuck with what I knew.

However, in my code as it stands the scale_fill_manual call needs to be explicitly passed variables to define fill colours, such as 'europe' = 'blue'. These variables will vary depending on the data I am processing, so with the script in its current form, I will need to manually edit the ggplot part of the script for each group of data series. I know that would be be time-consuming and I strongly suspect it would also be very prone to errors.

Q. Ideally I would like to be able to programmatically extract and define the required values for the scale_fill_manual call from a previously declared list of values (in this case from list_of_regions) matched to a previously declared list of colours, but I can't think of a way to achieve this. Do you have any ideas?

解决方案

Does this help?

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))

这篇关于以编程方式指定scale_fill_manual ggplot调用中的颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆