如何使用ggplot2在条形图上覆盖一条线?

时间:2010-12-02 06:22:41

标签: r ggplot2

我正在寻找一种绘制包含两个不同系列的条形图的方法,隐藏其中一个系列的条形图,而是有一条线(如果可能的话,光滑)穿过隐藏系列的条形顶部已经(类似于如何在直方图上叠加频率多项式)。我已经尝试过以下示例,但似乎遇到了两个问题。

首先,我需要按组总结(总计)数据,其次,我想将其中一个系列(df2)转换为一行。

df <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,1,2,2,3,3))  
df2 <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,4,3,5,1,2))  
ggplot(df, aes(x=grp, y=val)) +   
    geom_bar(stat="identity", alpha=0.75) +  
    geom_bar(data=df2, aes(x=grp, y=val), stat="identity", position="dodge")

2 个答案:

答案 0 :(得分:19)

您可以通过多种方式获得小组合计。其中之一是

with(df, tapply(val, grp, sum))

为简单起见,您可以将条形和线条数据组合到一个数据集中。

df_all <- data.frame(grp = factor(levels(df$grp)))
df_all$bar_heights <- with(df, tapply(val, grp, sum))
df_all$line_y <- with(df2, tapply(val, grp, sum))

条形图使用分类x轴。要叠加一条线,您需要将轴转换为数字。

ggplot(df_all) +
   geom_bar(aes(x = grp, weight = bar_heights)) +
   geom_line(aes(x = as.numeric(grp), y = line_y))

enter image description here

答案 1 :(得分:13)

也许您的示例数据不能代表您正在使用的实际数据,但没有为df2绘制的行。每个x和y值只有一个值。以下是df2的修改版本,其中包含足够的数据点来构建行:

df <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,2,3,1,2,3))
df2 <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,4,3,5,0,2))

p <- ggplot(df, aes(x=grp, y=val)) 
p <- p + geom_bar(stat="identity", alpha=0.75) 

p + geom_line(data=df2, aes(x=grp, y=val), colour="blue")

或者,如果您的上述示例数据正确无误,则可以将此信息绘制为geom_point(data = df2, aes(x = grp, y = val), colour = "red", size = 6)的点。你可以根据自己的喜好显然改变颜色和大小。

编辑:回应评论

我不完全确定直方图上的频率多项式的视觉应该是什么样子。 x值是否应该相互连接?其次,你一直指的是想要的行,但你的代码显示geom_bar(),我认为这不是你想要的?如果您想要线条,请使用geom_lines()。如果上述两个假设是正确的,那么这是一种方法:

 #First let's summarise df2 by group
 df3 <- ddply(df2, .(grp), summarise, total = sum(val))
>  df3
  grp total
1   A     5
2   B     8
3   C     3

#Second, let's plot df3 as a line while treating the grp variable as numeric

p <- ggplot(df, aes(x=grp, y=val))
p <- p + geom_bar(alpha=0.75, stat = "identity") 
p + geom_line(data=df3, aes(x=as.numeric(grp), y=total), colour = "red")