[英]How can a line be overlaid on a bar plot using ggplot2?
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")
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. 条形图使用分类x轴。 To overlay a line you will need to convert the axis to be numeric.
要叠加一条线,您需要将轴转换为数字。
ggplot(df_all) +
geom_bar(aes(x = grp, weight = bar_heights)) +
geom_line(aes(x = as.numeric(grp), y = line_y))
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
. 也许您的样本数据不能代表您正在使用的实际数据,但是没有为
df2
绘制的行。 There is only one value for each x and y value. 每个x和y值只有一个值。 Here's a modifed version of your
df2
with enough data points to construct lines: 这是你的
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)
. 或者,如果上面的示例数据是正确的,您可以将此信息绘制为带有
geom_point(data = df2, aes(x = grp, y = val), colour = "red", size = 6)
的点geom_point(data = df2, aes(x = grp, y = val), colour = "red", size = 6)
。 You can obviously change the color and size to your liking. 您可以根据自己的喜好显然改变颜色和大小。
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?
x值是否应该相互连接? Secondly, you keep referring to wanting lines but your code shows
geom_bar()
which I assume isn't what you want? 其次,你一直指的是想要的行但你的代码显示
geom_bar()
,我认为这不是你想要的? If you want lines, use geom_lines()
. 如果需要行,请使用
geom_lines()
。 If the two assumptions above are correct, then here's an approach to do that: 如果上述两个假设是正确的,那么这是一种方法:
#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")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.