在构面之间更改配色方案

Ros*_*oss 4 r ggplot2

我有一个data.frame,类似于以下内容:

set.seed(100)

df <- data.frame(year = rep(2011:2014, 3), 
                 class = rep(c("high", "middle", "low"), each = 4), 
                 age_group = rep(1:3, each = 4), 
                 value = sample(1:2, 12, rep = TRUE))
Run Code Online (Sandbox Code Playgroud)

我希望通过facet-ing(通过变量age_group)生成三个与以下代码生成的图相似的图:

library(ggplot2)
blue <- c("#bdc9e1", "#74a9cf", "#0570b0")
ggplot(df) + geom_bar(aes(x = year, y = value, 
                          fill = factor(class, levels = c("high", "middle", "low"))), 
                      stat = "identity") + 
  scale_fill_manual(values = c(blue)) +
  guides(fill = FALSE)
Run Code Online (Sandbox Code Playgroud)

但是,每个方面都有不同的配色方案,其中所有颜色均由我自己指定。

我似乎想要这里发生的事情的更特定版本:ggplot2:更改条形图中每个方面的颜色

因此,使用我提供的数据,我希望获得三个多面图,并按age_group每个图的填充级别(由的水平)划分class,所有颜色(总共9种)将由我自己指定。

编辑:为澄清起见,以下代码的确提供了我想最终涉及的方面:

ggplot(df) + geom_bar(aes(x = year, y = value, 
                          fill = factor(class, levels = c("high", "middle", "low"))), 
                      stat = "identity") + 
  scale_fill_manual(values = c(blue)) +
  guides(fill = FALSE) + 
  facet_wrap(~ age_group)
Run Code Online (Sandbox Code Playgroud)

通过class变量增加了对颜色子集的控制级别。

Mar*_*son 7

我不确定您为什么要这样做,因此很难知道我是否提出了解决您的实际用例的方法。

First, I generated a different data set that actually has each class in each age_group:

set.seed(100)

df <- data.frame(year = rep(2011:2014, 3), 
                 class = rep(c("high", "middle", "low"), each = 12), 
                 age_group = rep(1:3, each = 4), 
                 value = sample(1:2, 36, rep = TRUE))
Run Code Online (Sandbox Code Playgroud)

If you are looking for a similar dark-to-light gradient within each age_group you can accomplish this directly using alpha and not worry about adding extra data columns:

ggplot(df) +
  geom_bar(aes(x = year, y = value, 
               fill = factor(age_group)
               , alpha = class ), 
           stat = "identity") + 
  facet_wrap(~age_group) +
  scale_alpha_discrete(range = c(0.4,1)) +
  scale_fill_brewer(palette = "Set1"
                    , name = "age_group")
Run Code Online (Sandbox Code Playgroud)

Here, I set the range of the alpha to give reasonably visible colors, and just chose a default palette from RColorBrewer to show the idea. This gives:

在此处输入图片说明

It also gives a relatively usable legend as a starting point, though you could modify it further (here is a similar legend answer I gave to a different question: /sf/answers/2733288421/ )

Alternatively, if you really, really want to specify the colors yourself, you can add a column to the data, and base the color off of that:

df$forColor <-
  factor(paste0(df$class, " (", df$age_group , ")")
         , levels = paste0(rep(c("high", "middle", "low"), times = 3)
                           , " ("
                           , rep(1:3, each = 3)
                           , ")") )
Run Code Online (Sandbox Code Playgroud)

Then, use that as your fill. Note here that I am using the RColorBrewer brewer.pal to pick colors. I find that the first color is too light to show up for bars like this, so I excluded it.

ggplot(df) +
  geom_bar(aes(x = year, y = value, 
               fill = forColor), 
           stat = "identity") + 
  scale_fill_manual(values = c(brewer.pal(4, "Blues")[-1]
                               , brewer.pal(4, "Reds")[-1]
                               , brewer.pal(4, "Purples")[-1]
                               )
                    , name = "Class (age_group)") +
  facet_wrap(~age_group)
Run Code Online (Sandbox Code Playgroud)

gives:

在此处输入图片说明

The legend is rather busy, but could be modified similar to the other answer I linked to. This would then allow you to set whatever 9 (or more, for different use cases) colors you wanted.