【问题标题】:How do I manually set geom_bar fill color in ggplot如何在 ggplot 中手动设置 geom_bar 填充颜色
【发布时间】:2013-08-16 07:02:46
【问题描述】:

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

我的问题是我需要制作几个这样的图表,并且我希望颜色在所有这些图表中保持一致。由于“类型”变量在我将要使用的几个数据集中以不同的顺序出现,因此我需要为每种类型手动设置颜色。我认为这个问题: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。

【问题讨论】:

标签: r colors ggplot2


【解决方案1】:

我猜你看过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 中的数据相对应。有一些方法可以使用您当前的代码,但它们对于创建标准条形图是非常规的。

【讨论】:

  • 该答案可以创建我在链接到的图像中显示的示例图,但它无助于解决真正的问题。我有 5-6 个相似的数据集需要生成这些图表,并且我想确保每种类型的颜色在每个图表中保持相同。因此,我想手动将一种颜色分配给“Waste Wood”,将另一种颜色分配给“MSW”,这样每次我重现图表时,颜色都是相同的。您提供的示例似乎让 ggplot 每次运行脚本时都会选择与每种类型关联的颜色。
  • 啊,我明白了。你的因素有问题吗? R 有这种令人讨厌的习惯,即以一种表面上异想天开的方式对变量进行重新排序。您可以强制 ggplot 以您喜欢的任何方式对变量进行排序。见here。使用这些技巧,一旦您按照相同的顺序放置每个标签,您的每个地块将具有相同的颜色填充顺序。
  • 那也没用。它肯定对数据框中的因素进行了重新排序,因为类型和填充颜色之间的关系发生了变化,但并不是每种类型都在我正在使用的每个数据集中都有表示。我真正需要的是一种表达方式:If Type="Y" then fill=cbbPalette[x]
  • 将您的数据集放入一个聚合数据框中,然后添加一个类型列(用于稍后按类型分组和绘图)。由于您的变量将位于相同的列中,因此 ggplot 会将您的因子映射到跨类型的相同颜色(即使某些类型中缺少一个因子)。最后,使用 facet 创建单独的类型图,例如 ggplot(df, aes(x=cond, y=yval)) + geom_bar() + scale_fill_manual(values=cbbPalette) + facet_grid(. ~ type)。
【解决方案2】:

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_cover 由color_table 给出的正确颜色表示。首先,我们必须确保数据集df 中的Land_cover 变量是一个因子变量,其顺序与我们要放置在每种土地覆盖类型上的颜色相同。我们使用来自color_table 的订单来做到这一点:

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

现在,使用正确颜色进行绘图的最简单的方法是,正如 Jay B. Martin 在 cmets 中建议的那样,使用 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) 

但是如果你想为每个区域制作一个单独的图呢?例如,您希望将每个图保存为单独的文件。

问题

如果我们基本上创建一个小循环,在其中选择数据子集并重用我们上面使用的代码(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)
  }

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

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

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

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

解决方案 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):

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

【讨论】:

  • 现在用 geom_bar 试试这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 2019-07-09
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
  • 2012-04-18
相关资源
最近更新 更多