如何在ggplot中手动设置geom_bar填充颜色

时间:2013-08-14 10:54:53

标签: r colors ggplot2

我正在尝试使用ggplot创建多个图表。这些图是一系列条形图,它们一起描述了一条线EXAMPLE(顺便说一句,是的,我意识到调色板是丑陋的,它是色盲友好的,这对我的观众很重要)

我的问题是我需要制作其中的几个图表,并希望颜色在所有图表中保持一致。由于“Type”变量在我将要使用的几个数据集中以不同的顺序出现,我需要为每种类型手动设置颜色。我认为这个问题:How to manually fill colors in a ggplot2 histogram会得到答案,但是当我尝试时,它会将图例中的名称更改为颜色的十六进制定义,但颜色本身会返回到ggplot的默认调色板。

这是我到目前为止的代码:

  cbbPalette <- c("#000000", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")

 ggplot()+
    scale_fill_manual(values=cbbPalette)+
    geom_bar(data=subset(eten, Type=="Waste Wood"), aes(x=Tprod, y=acost, fill=cbbPalette[1], width=MGGEY+25), stat="identity")+
    geom_bar(data=subset(eten, Type=="Agricultural Residue"), aes(x=Tprod, y=acost, fill=cbbPalette[2], width=MGGEY+25), stat="identity")+
    geom_bar(data=subset(eten, Type=="Forest Residue"), aes(x=Tprod, y=acost, fill=cbbPalette[3], width=MGGEY+25), stat="identity")+
    geom_bar(data=subset(eten, Type=="Herbaceous Energy Crop"), aes(x=Tprod, y=acost, fill=cbbPalette[4], width=MGGEY+25), stat="identity")+
    geom_bar(data=subset(eten, Type=="MSW"), aes(x=Tprod, y=acost, fill=cbbPalette[5], width=MGGEY+25), stat="identity")+
    scale_y_continuous("Average Cost", labels = dollar, expand=c(0,0))+
    scale_x_continuous("Million Gallons of Gasoline Equivalent", expand=c(0,0))+
    theme(legend.position="bottom", panel.background=element_rect(colour = NA, fill = "white"), axis.line=element_line(), panel.grid.major.y=element_line(colour="black"), panel.grid.minor=element_blank())

我的R专业水平相当低,所以我可能会遗漏一些简单的东西,但我不能让它独立工作。在此先感谢您的帮助。

更新:我无意中粘贴了不正确的代码版本,“填充”命令又回到了我最好的猜测。示例数据集是here

2 个答案:

答案 0 :(得分:6)

我猜你已经看过显示here的ggplot色盲示例了吗?如果没有您的数据,我只能推测您的geom_bar调用会产生关于应用填充更改的层的歧义,因为您对ggplot的初始调用没有aes参数。尝试将所有数据移动到单个数据帧中,并在初始调用ggplot时引用它,例如,

ggplot(df, aes(x=cond, y=yval)) +
    geom_bar() + 
    scale_fill_manual(values=cbbPalette)

其中df是包含数据的数据框,而aes是变量之间的映射。这使得ggplot明确表示你希望geom_bar的填充颜色与df中的数据相对应。有一些方法可以使用您当前的代码,但它们对于创建标准条形图是非常规的。

答案 1 :(得分:3)

Jay B. Martin的answer并未完全回答这个问题。因此,尽管这个问题已经很久了,但是这里有一个解决方案,可供将来参考。我们为可重现的示例提供一些数据:

color_table <- tibble(
  Land_cover = c("Agriculture", "Forest", "Ocean", "Lake", "Populated"),
  Color = c("yellow", "darkgreen", "blue4", "lightblue", "maroon3")
  )

df <- data.frame(
  Region = c(rep(1,5), rep(2,5)),
  Area_no = c(1,2,3,4,5,1,2,3,4,5),
  Land_cover = c("Agriculture", "Forest", "Agriculture", "Agriculture", "Lake", 
                 "Lake", "Populated", "Populated", "Ocean", "Populated"), 
  Square_km = c(10,15,7,12,3, 5,30,20,40,10)
  )

因此,我们想使用df为每个Region绘制图形,其中Land_covercolor_table给出的正确颜色表示。首先,我们必须确保数据集Land_cover中的df变量是一个因子变量,其顺序与我们要在每种类型的土地覆被上放的颜色的顺序相同。我们使用color_table中的顺序:

df$Land_cover <- factor(df$Land_cover, levels = color_table$Land_cover)

现在,正如杰伊·B·马丁(Jay B. Martin)在评论中建议的那样,使用正确的颜色进行绘制的最简单方法是使用facet_grid()或facet_wrap():

ggplot(df, aes(x = Area_no, y = Square_km, fill = Land_cover)) +
  geom_col() +
  scale_fill_manual(values = color_table$Color) +
  facet_grid(.~Region) 

ggplot using facet 但是,如果您想为每个地区绘制一个单独的图,该怎么办?例如,您要将每个图另存为单独的文件。

问题

如果我们基本上做一个小循环,在其中选择数据的子集并重用上面使用的代码(facet_grid除外),我们显然会得到错误的颜色(此处显示为区域2):

for (region in 1:2){
  gg <- ggplot(subset(df, Region %in% region), aes(x = Area_no, y = Square_km, fill = 
  Land_cover)) +
    geom_col() + 
    scale_fill_manual(values = color_table$Color) 
  ggsave(paste0("Areas_region_", region, ".png"), width = 5, height = 3)
  }

Plot with wrong colours

有两种方法可以获取正确的颜色:

解决方案1. drop = FALSE(图例显示所有类别)

到目前为止,在drop = FALSE中添加scale_fill_manual是最简单的。然后,您将获得corrcet颜色,图例将显示所有可能的类别,而不仅是图中的类别:

for (region in 1:2){
  gg <- ggplot(subset(df, Region %in% region), aes(x = Area_no, y = Square_km, fill = 
  Land_cover)) +
    geom_col() + 
    scale_fill_manual(values = color_table$Color, drop = FALSE) 
  ggsave(paste0("Areas_region_", region, ".png"), width = 5, height = 3)
  }

Plot with correct colours and legend for all categories

解决方案2.为每个图选择颜色(图例仅显示图中显示的类别)

如果由于某种原因您不希望图例显示所有可能的类别(例如,如果类别很多),则需要为每个图选择正确的颜色:

library(magrittr)
for (region in 1:2){
  df_plot <- subset(df, Region %in% region)
  actual_cover <- df_plot$Land_cover %>% as.numeric() %>% table() %>% names() %>% as.numeric()
  gg <- ggplot(df_plot, aes(x = Area_no, y = Square_km, fill = Land_cover)) +
    geom_col() + 
    scale_fill_manual(values = color_table$Color[actual_cover])
  ggsave(paste0("Areas_region_", region, "ver3.png"), width = 5, height = 3)
  }

,将导致以下绘图(对于区域2):    Plot with correct colours and legend for all categories

我们在这里实际要做的是制作一个向量actual_cover,其中包含当前绘图中实际使用的颜色(数字1-6)。结果,图例仅包含图中存在的类别,而颜色仍然正确。