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

时间:2022-07-22 14:56:02

I'm looking for a way to plot a bar chart containing two different series, hide the bars for one of the series and instead have a line (smooth if possible) go through the top of where bars for the hidden series would have been (similar to how one might overlay a freq polynomial on a histogram). I've tried the example below but appear to be running into two problems.

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

First, I need to summarize (total) the data by group, and second, I'd like to convert one of the series (df2) to a line.

首先,我需要按组总结(总计)数据,其次,我想将其中一个系列(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 个解决方案

#1


12  

Perhaps your sample data aren't representative of the real data you are working with, but there are no lines to be drawn for df2. There is only one value for each x and y value. Here's a modifed version of your df2 with enough data points to construct lines:

也许您的样本数据不能代表您正在使用的实际数据,但是没有为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")

Alternatively, if your example data above is correct, you can plot this information as a point with geom_point(data = df2, aes(x = grp, y = val), colour = "red", size = 6). You can obviously change the color and size to your liking.

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

EDIT: In response to comment

编辑:回应评论

I'm not entirely sure what the visual for a freq polynomial over a histogram is supposed to look like. Are the x-values supposed to be connected to one another? Secondly, you keep referring to wanting lines but your code shows geom_bar() which I assume isn't what you want? If you want lines, use geom_lines(). If the two assumptions above are correct, then here's an approach to do that:

我不完全确定直方图上的频率多项式的视觉应该是什么样子。 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")

#2


18  

You can get group totals in many ways. One of them is

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

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

For simplicity, you can combine bar and line data into a single dataset.

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

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

Bar charts use a categorical x-axis. To overlay a line you will need to convert the axis to be numeric.

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

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

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

#1


12  

Perhaps your sample data aren't representative of the real data you are working with, but there are no lines to be drawn for df2. There is only one value for each x and y value. Here's a modifed version of your df2 with enough data points to construct lines:

也许您的样本数据不能代表您正在使用的实际数据,但是没有为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")

Alternatively, if your example data above is correct, you can plot this information as a point with geom_point(data = df2, aes(x = grp, y = val), colour = "red", size = 6). You can obviously change the color and size to your liking.

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

EDIT: In response to comment

编辑:回应评论

I'm not entirely sure what the visual for a freq polynomial over a histogram is supposed to look like. Are the x-values supposed to be connected to one another? Secondly, you keep referring to wanting lines but your code shows geom_bar() which I assume isn't what you want? If you want lines, use geom_lines(). If the two assumptions above are correct, then here's an approach to do that:

我不完全确定直方图上的频率多项式的视觉应该是什么样子。 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")

#2


18  

You can get group totals in many ways. One of them is

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

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

For simplicity, you can combine bar and line data into a single dataset.

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

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

Bar charts use a categorical x-axis. To overlay a line you will need to convert the axis to be numeric.

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

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

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