更改 ggplot 中一个闪避条的填充颜色。

7
我希望仅针对最后一组数据,改变条形图的顺序,以突出显示。我使用了scale_fill_manual(),但效果不太好。
以下是我的代码:
 x<-c(rep(c("Type1", "Type2"),4))
     y<-c(4,5,6,7,3,4,5,2)
     time<-c(2010,2010,2011,2011,2012,2012,2013,2013)
     z<-data.frame(type = x, val=y, Time = time)

     ggplot(data = z, aes(x=Time,y=val)) +
       geom_bar(stat = "identity", position = "dodge", aes(fill=type))+
       scale_fill_manual(values = c(rep(c("white", "gray51"),3),"white","red"))

这是输出结果:

enter image description here

我希望图表看起来像这样: enter image description here 有没有办法实现这个效果?我会感激任何帮助。我看了一下在ggplot中仅更改一个条形的颜色,但似乎不适用于分组数据。

你是否很在意图例中没有任何红色?这将是这个问题的棘手部分... - Gregor Thomas
@gregor 我认为如果图例没有红色会更好。然而,我是R和ggplot2的初学者。所以,如果您能指导我如何在有或没有图例的情况下实现它,我将不胜感激。非常感谢您的帮助,我真的很感激。 - watchtower
请参见我的答案末尾的编辑,以保持图例中的红色不变。 - Gregor Thomas
3个回答

11

我的一般口号是,ggplot非常擅长绘制您提供的数据。如果您想要它绘制不同的内容,最简单的方法通常是修改数据。

z$type2 = as.character(z$type)
z$type2[z$type == "Type2" & z$Time == 2013] = "Type2 "

在你想要突出显示的行的"Type2 "中,我添加了一个隐蔽的额外空格。它将成为一个不同的因素水平,并获得自己的颜色(甚至可以使用字母表顺序的默认值强制转换为一个好的顺序)。但在图例标签中它看起来是相同的。

ggplot(data = z, aes(x=Time,y=val)) +
    geom_bar(stat = "identity", position = "dodge", aes(fill=type2))+
    scale_fill_manual(values = c("white", "gray50", "red"))

在此输入图像说明

我原本以为从图例中省略红色很困难,但是这个答案向我展示只需要将breaks = c("Type1", "Type2")作为一个参数添加到scale_fill_manual函数中即可。


7

那么用边框来突出显示该栏如何呢?例如:

z$hi = with(z, ifelse(type=="Type2" & Time==2013, "Y","N"))

ggplot(data = z, aes(x=Time,y=val)) +
  geom_bar(stat = "identity", position = "dodge", 
           aes(fill=type, colour=hi), size=1) +
  scale_fill_manual(values=c("gray51","white")) +
  scale_colour_manual(values=c(NA,"red")) +
  guides(colour=FALSE)

这里输入图片描述

更新:鉴于您的评论,我认为折线图可以更轻松地观察每个type之间的趋势和关系。例如:

ggplot(data = z, aes(x=Time,y=val,colour=type)) +
  geom_line() +
  geom_point() +
  geom_point(data=z[z$hi=="Y",], aes(x=Time, y=val), size=4, pch=1, 
             colour=hcl(195,100,40), stroke=1) +
  scale_y_continuous(limits=c(0,max(z$val))) +
  theme_bw()

enter image description here


1
调用内部的颜色比下面我两步解决方案的颜色要好得多。 - Mark Peterson
1
@gregor和eipi10--这太棒了!我很好奇--你们认为有更好的geom_type来表示上面的数据吗?我读过一位资深SO成员的帖子,如果我必须“hack”我们的方式(即更改数据集)来表示ggplot2上的某些内容,那么我可能没有选择正确的geom。你认为用其他geom_替换geom_bar会更好吗?我是一个初学者,已经开始使用ggplot2约5天。所以,我不确定,想请教你们。我从你们在SO上的帖子中学到了很多。 - watchtower
2
不,你做得很好。这些都不像是hackish的。这两个都是geom_bar自然而然就有的。我认为我们两个解决方案的教训在于 - 如果你想要突出某些东西,让ggplot帮你完成的简单方法是添加一列到你的数据中,指示哪些内容需要突出显示。 - Gregor Thomas
3
我认为在这里使用折线图会更好。我添加了一个示例,这样你就可以明白我的意思了。 - eipi10

2

使用图例可以很容易地完成,尽管您可能需要小心突然改变颜色而让用户感到困惑。只需向x变量添加一个额外的类别来指示您希望进行高亮显示的位置即可。

x<- xHigh <- c(rep(c("Type1", "Type2"),4))
xHigh[length(xHigh)] <- "Type2_highlight"

myHighlight <- rep("No",length(x))
myHighlight[length(myHighlight)] <- "Yes"
y<-c(4,5,6,7,3,4,5,2)
time<-c(2010,2010,2011,2011,2012,2012,2013,2013)
z<-data.frame(type = x, xHigh = xHigh, val=y, Time = time, myHighlight = myHighlight)

ggplot(data = z, aes(x=Time,y=val)) +
  geom_bar(stat = "identity", position = "dodge", aes(fill=xHigh))+
  scale_fill_manual(values = c(Type1 = "white", Type2 = "gray51", Type2_highlight = "red"))

另一种突出显示特定条形的潜在选项是在其周围绘制一个框,如下所示:

enter image description here

ggplot(data = z, aes(x=Time,y=val)) +
  geom_bar(stat = "identity", position = "dodge", aes(fill=type))+
  scale_fill_manual(values = c(Type1 = "white", Type2 = "gray51")) +
  geom_bar(aes(linetype = xHigh)
           , fill = NA
           , stat = "identity", position = "dodge"
           , col = "red"
           , show.legend = FALSE) +
  scale_linetype_manual(values = c(Type1 = 0
                                   , Type2 = 0
                                   , Type2_highlight = 1))

希望能有所帮助。
以下是需要翻译的内容:

enter image description here


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